/*!
 * jQuery JavaScript 库 v3.7.0
 * https://jquery.com/
 *
 * 版权所有 OpenJS 基金会和其他贡献者
 * 在麻省理工学院许可下发布
 * https://jquery.org/license
 *
 * 日期：2023-05-11T18:29Z
 */
（函数（全局，工厂）{

	“使用严格”；

	if ( typeof module === "object" && typeof module.exports === "object" ) {

		// 对于 CommonJS 和类似 CommonJS 的环境，其中有一个合适的 `window`
		// 存在，执行工厂并获取 jQuery。
		// 对于没有带有 `document` 的 `window` 的环境
		//（例如 Node.js），将工厂公开为 module.exports。
		// 这强调了创建一个真正的 `window` 的必要性。
		// 例如 var jQuery = require("jquery")(window);
		// 有关详细信息，请参阅票证 trac-14549。
		module.exports = global.document ?
			工厂（全球，真实）：
			函数（w）{
				如果（！w.document）{
					throw new Error( "jQuery 需要一个带有文档的窗口" );
				}
				返回工厂（w）；
			};
	} 别的 {
		工厂（全球）；
	}

// 如果窗口还没有定义则传递这个
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {

// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
// 当非严格代码（例如 ASP.NET 4.5）访问严格模式时抛出异常
// arguments.callee.caller (trac-13335)。但是从 jQuery 3.0 (2016) 开始，严格模式应该是常见的
// 足以让所有此类尝试都在 try 块中得到保护。
“使用严格”；

变量 arr = [];

var getProto = Object.getPrototypeOf;

var slice = arr.slice;

var flat = arr.flat ？函数（数组）{
	返回 arr.flat.call(array);
}：函数（数组）{
	返回 arr.concat.apply([], array);
};


var push = arr.push;

var indexOf = arr.indexOf;

var class2type = {};

var toString = class2type.toString;

var hasOwn = class2type.hasOwnProperty;

var fnToString = hasOwn.toString;

var ObjectFunctionString = fnToString.call( Object );

var 支持 = {};

var isFunction = function isFunction(obj){

		// 支持：Chrome <=57，Firefox <=52
		// 在某些浏览器中，typeof 为 HTML <object> 元素返回“function”
		//（即，`typeof document.createElement( "object" ) === "function"`）。
		// 我们不想将 *any* DOM 节点归类为函数。
		// 支持：QtWeb <=3.8.5，WebKit <=534.34，wkhtmltopdf 工具 <=0.12.5
		// 另外对于旧的 WebKit，typeof 返回 HTML 集合的“函数”
		//（例如，`typeof document.getElementsByTagName("div") === "function"`）。(gh-4756)
		return typeof obj === "function" && typeof obj.nodeType !== "number" &&
			typeof obj.item !== "函数";
	};


var isWindow = function isWindow(obj){
		return obj != null && obj === obj.window;
	};


var 文档 = window.document;



	var preservedScriptAttributes = {
		类型：真实，
		来源：真实，
		随机数：真实的，
		无模块：真
	};

	函数 DOMEval（代码、节点、文档）{
		文件 = 文件 || 文档;

		变种我，瓦尔，
			script = doc.createElement("脚本");

		script.text = 代码；
		如果（节点）{
			对于（我在 preservedScriptAttributes 中）{

				// 支持：Firefox 64+、Edge 18+
				// 一些浏览器不支持脚本的“nonce”属性。
				// 另一方面，仅使用 `getAttribute` 是不够的，因为
				// 无论何时，`nonce` 属性都会重置为空字符串
				// 变成浏览上下文连接。
				// 请参阅 https://github.com/whatwg/html/issues/2369
				// 参见 https://html.spec.whatwg.org/#nonce-attributes
				// 添加 `node.getAttribute` 检查是为了
				// `jQuery.globalEval` 这样它就可以伪造一个包含 nonce 的节点
				// 通过一个对象。
				val =节点[我]|| 节点.getAttribute && 节点.getAttribute( i );
				如果（值）{
					script.setAttribute(i, val);
				}
			}
		}
		doc.head.appendChild(脚本).parentNode.removeChild(脚本);
	}


函数 toType(obj){
	如果（对象==空）{
		返回对象+“”；
	}

	// 支持：Android <=2.3 only (functionish RegExp)
	返回类型 obj === “对象” || typeof obj === “函数” ?
		class2type[ toString.call( obj ) ] || “目的” ：
		对象类型；
}
/* 全局符号 */
// 在 .eslintrc.json 中定义这个全局变量会产生使用全局变量的危险
// 在另一个地方无人看管，只为这个模块定义全局似乎更安全



变种版本=“3.7.0”，

	rhtmlSuffix = /HTML$/i,

	// 定义 jQuery 的本地副本
	jQuery = 函数（选择器，上下文）{

		// jQuery 对象实际上只是初始化构造函数的“增强”
		// 如果调用 jQuery 则需要初始化（如果不包含则允许抛出错误）
		返回新的 jQuery.fn.init（选择器，上下文）；
	};

jQuery.fn = jQuery.prototype = {

	// 当前使用的 jQuery 版本
	jquery：版本，

	构造函数：jQuery，

	// jQuery 对象的默认长度为 0
	长度：0，

	toArray：函数（）{
		返回 slice.call(this);
	},

	// 获取匹配元素集中的第N个元素 OR
	// 获取整个匹配元素集作为一个干净的数组
	得到：函数（数字）{

		// 返回干净数组中的所有元素
		如果（数字==空）{
			返回 slice.call(this);
		}

		// 只返回集合中的一个元素
		返回数 < 0 ？这个 [ num + this.length ] : 这个 [ num ];
	},

	//获取一个元素数组并将其压入堆栈
	//（返回新的匹配元素集）
	pushStack：函数（元素）{

		// 构建一个新的 jQuery 匹配元素集
		var ret = jQuery.merge( this.constructor(), elems );

		// 将旧对象添加到堆栈中（作为参考）
		ret.prevObject = this;

		// 返回新形成的元素集
		返还；
	},

	// 为匹配集中的每个元素执行回调。
	每个：函数（回调）{
		返回 jQuery.each(this, callback);
	},

	地图：功能（回调）{
		返回 this.pushStack( jQuery.map( this, function( elem, i ) {
			返回 callback.call(elem, i, elem);
		} );
	},

	切片：函数（）{
		返回 this.pushStack( slice.apply( this, arguments ) );
	},

	第一：功能（）{
		返回 this.eq( 0 );
	},

	最后：功能（）{
		返回 this.eq(-1);
	},

	甚至：函数（）{
		返回 this.pushStack( jQuery.grep( this, function( _elem, i ) {
			返回 ( i + 1 ) % 2;
		} );
	},

	奇数：函数（）{
		返回 this.pushStack( jQuery.grep( this, function( _elem, i ) {
			返回我 % 2；
		} );
	},

	当量：函数（我）{
		var len = this.length,
			j = +i + ( i < 0 ? len : 0 );
		返回 this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
	},

	结束：功能（）{
		返回 this.prevObject || 这个。构造函数（）；
	},

	// 仅限内部使用。
	// 表现得像数组的方法，而不像 jQuery 方法。
	推推，
	排序：arr.sort，
	拼接：arr.拼接
};

jQuery.extend = jQuery.fn.extend = function() {
	var options, name, src, copy, copyIsArray, clone,
		目标=参数[0]|| {},
		我 = 1,
		length = arguments.length,
		深=假；

	// 处理深拷贝情况
	如果（目标类型===“布尔值”）{
		深=目标；

		// 跳过布尔值和目标
		目标=参数[我]|| {};
		我++；
	}

	// 处理目标是字符串或其他东西的情况（可能在深层复制中）
	if ( typeof target !== "object" && !isFunction( target ) ) {
		目标={}；
	}

	// 如果只传递一个参数，则扩展 jQuery 本身
	如果（我===长度）{
		目标=这个；
		我 - ;
	}

	对于（；我<长度；我++）{

		// 只处理非空/未定义的值
		如果 ( ( options = arguments[ i ] ) != null ) {

			// 扩展基础对象
			对于（选项中的名称）{
				复制=选项[名称]；

				// 防止 Object.prototype 污染
				// 防止永无止境的循环
				如果（名称===“__proto__”||目标===复制）{
					继续;
				}

				// 如果我们要合并普通对象或数组，则递归
				如果（深&&复制&&（jQuery.isPlainObject（复制）||
					( copyIsArray = Array.isArray( 复制 ) ) ) ) {
					src = 目标[名称];

					// 确保源值的类型正确
					if ( copyIsArray && !Array.isArray( src ) ) {
						克隆 = [];
					} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
						克隆={}；
					} 别的 {
						克隆=源；
					}
					copyIsArray = false;

					// 永远不要移动原始对象，克隆它们
					target[名称] = jQuery.extend(深, 克隆, 复制);

				// 不要引入未定义的值
				} 否则如果（复制！==未定义）{
					目标[名称] = 副本；
				}
			}
		}
	}

	// 返回修改后的对象
	返回目标；
};

jQuery.扩展（{

	// 页面上的每个 jQuery 副本都是唯一的
	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),

	// 假设 jQuery 在没有 ready 模块的情况下就绪
	就绪：真，

	错误：函数（味精）{
		抛出新错误（味精）；
	},

	noop：函数（）{}，

	isPlainObject：函数（obj）{
		变量原型，Ctor；

		// 检测明显的负数
		// 使用 toString 而不是 jQuery.type 来捕获宿主对象
		如果（！obj || toString.call（obj）！==“[对象对象]”）{
			返回假；
		}

		proto = getProto(obj);

		// 没有原型的对象（例如，`Object.create( null )`）是普通的
		如果（！原型）{
			返回真；
		}

		// 具有原型的对象是普通的，当且仅当它们是由全局对象函数构造的
		Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
	},

	isEmptyObject：函数（obj）{
		变量名称；

		对于（对象中的名称）{
			返回假；
		}
		返回真；
	},

	// 在提供的上下文中评估脚本；回落到全球
	// 如果没有指定。
	globalEval：函数（代码、选项、文档）{
		DOMEval( code, { nonce: options && options.nonce }, doc );
	},

	每个：函数（obj，回调）{
		可变长度，我= 0；

		如果（isArrayLike（obj））{
			length = obj.length;
			对于（；我<长度；我++）{
				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
					休息;
				}
			}
		} 别的 {
			对于（我在对象中）{
				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
					休息;
				}
			}
		}

		返回对象；
	},


	// 检索 DOM 节点数组的文本值
	文本：函数（元素）{
		可变节点，
			回复=“”，
			我 = 0,
			nodeType = elem.nodeType;

		如果（！节点类型）{

			// 如果没有 nodeType，这应该是一个数组
			while ( ( node = elem[ i++ ] ) ) {

				// 不遍历注释节点
				ret += jQuery.text(节点);
			}
		} else if ( 节点类型 === 1 || 节点类型 === 9 || 节点类型 === 11 ) {
			返回 elem.textContent；
		} else if ( 节点类型 === 3 || 节点类型 === 4 ) {
			返回 elem.nodeValue；
		}

		// 不包括注释或处理指令节点

		返还；
	},

	// 结果仅供内部使用
	makeArray：函数（arr，结果）{
		var ret = 结果 || [];

		如果 ( arr != null ) {
			如果（isArrayLike（对象（arr））））{
				jQuery.merge(ret,
					类型 arr === “字符串”？
						[ 到达 ] : 到达
				);
			} 别的 {
				push.call(ret, arr);
			}
		}

		返还；
	},

	inArray: function( elem, arr, i ) {
		返回 arr == null ？-1 : indexOf.call( arr, elem, i );
	},

	isXMLDoc：函数（元素）{
		var namespace = elem && elem.namespaceURI,
			docElem = elem && ( elem.ownerDocument || elem ).documentElement;

		// 当 documentElement 尚不存在时假设为 HTML，例如 inside
		// 文档片段。
		返回 !rhtmlSuffix.test( 命名空间 || docElem && docElem.nodeName || "HTML" );
	},

	// 支持：仅限 Android <=4.0，仅限 PhantomJS 1
	// push.apply(_, arraylike) 在古老的 WebKit 上抛出
	合并：函数（第一，第二）{
		var len = +second.length,
			j = 0,
			i = first.length;

		对于 ( ; j < len; j++ ) {
			第一[ i++ ] = 第二 [ j ];
		}

		首先.length = i;

		先返回；
	},

	grep: function(elems, callback, invert) {
		var callbackInverse,
			匹配 = [],
			我 = 0,
			length = elems.length,
			callbackExpect = !invert;

		//遍历数组，只保存项目
		// 传递验证器函数
		对于（；我<长度；我++）{
			callbackInverse = !callback( elems[ i ], i );
			如果（callbackInverse！== callbackExpect）{
				matches.push(elems[i]);
			}
		}

		返回火柴；
	},

	// arg 仅供内部使用
	映射：函数（元素，回调，arg）{
		可变长度，价值，
			我 = 0,
			ret = [];

		// 遍历数组，将每个项目转换为它们的新值
		如果（isArrayLike（元素））{
			length = elems.length;
			对于（；我<长度；我++）{
				value = callback(elems[i],i,arg);

				如果（价值！=空）{
					ret.push( 值 );
				}
			}

		//遍历对象上的每个键，
		} 别的 {
			对于（我在元素中）{
				value = callback(elems[i],i,arg);

				如果（价值！=空）{
					ret.push( 值 );
				}
			}
		}

		// 展平任何嵌套数组
		返回平坦（ ret ）;
	},

	// 对象的全局 GUID 计数器
	指导：1，

	// jQuery.support 没有在 Core 中使用，但其他项目附加了它们的
	// 它的属性，所以它需要存在。
	支持：支持
});

如果（typeof Symbol ===“函数”）{
	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
}

// 填充 class2type 映射
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
	函数（_i，名称）{
		class2type[ "[object " + name + "]" ] = name.toLowerCase();
	});

函数 isArrayLike(obj){

	// 支持：仅限真正的 iOS 8.2（无法在模拟器中重现）
	// `in` 检查用于防止 JIT 错误 (gh-2145)
	// hasOwn 由于漏报这里没有使用
	// 关于 IE 中的节点列表长度
	var length = !!obj && obj && obj.length 中的“长度”，
		类型 = toType(obj);

	如果（isFunction（obj）|| isWindow（obj））{
		返回假；
	}

	返回类型 === “数组” || 长度=== 0 ||
		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}


函数节点名称（元素，名称）{

	返回 elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();

}
var pop = arr.pop;


var sort = arr.sort;


var 拼接 = arr.拼接；


var whitespace = "[\\x20\\t\\r\\n\\f]";


var rtrimCSS = new RegExp(
	"^" + 空格 + "+|((?:^|[^\\\\])(?:\\\\.)*)" + 空格 + "+$",
	“G”
);




// 注意：元素不包含自身
jQuery.contains = 函数（a，b）{
	var bup = b && b.parentNode;

	返回一个 === bup || !!( bup && bup.nodeType === 1 && (

		// 支持：IE 9 - 11+
		// IE 在 SVG 上没有 `contains`。
		a.包含？
			a.包含（bup）：
			a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
	));
};




// CSS 字符串/标识符序列化
// https://drafts.c​​sswg.org/cssom/#common-serializing-idioms
var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;

函数 fcssescape( ch, asCodePoint ) {
	如果（asCodePoint）{

		// U+0000 NULL 变成 U+FFFD 替换字符
		如果 ( ch === "\0" ) {
			返回“\uFFFD”；
		}

		// 控制字符和（取决于位置）数字作为代码点转义
		返回 ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
	}

	// 其他可能特殊的 ASCII 字符被反斜杠转义
	返回“\\”+ ch；
}

jQuery.escapeSelector = 函数（选择器）{
	返回 ( sel + "" ).replace( rcssescape, fcssescape );
};




var preferredDoc = 文档，
	pushNative = 推送；

（ 功能（） {

变量我，
	表达式,
	最外层上下文，
	排序输入，
	有重复，
	推=推本机，

	// 本地文档变量
	文档，
	文档元素，
	文档是HTML，
	rbuggyQSA,
	火柴，

	// 特定于实例的数据
	expando = jQuery.expando,
	dirruns = 0,
	完成 = 0,
	classCache = createCache(),
	tokenCache = createCache(),
	compilerCache = createCache(),
	nonnativeSelectorCache = createCache(),
	排序顺序 = 函数（a，b）{
		如果（a === b）{
			重复=真；
		}
		返回 0；
	},

	布尔值=“检查|选择|异步|自动对焦|自动播放|控制|延迟|禁用|隐藏|ismap|” +
		“循环|多个|打开|只读|需要|作用域”，

	// 常用表达

	// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
	标识符 = "(?:\\\\[\\da-fA-F]{1,6}" + 空格 +
		"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",

	// 属性选择器：https://www.w3.org/TR/selectors/#attribute-selectors
	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +

		// 运算符（捕获 2）
		"*([*^$|!~]?=)" + 空格 +

		// “属性值必须是 CSS 标识符 [capture 5] 或字符串 [capture 3 或 capture 4]”
		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"] )*)\"|(" + 标识符 + "))|)" +
		空格 + "*\\]",

	pseudos = ":(" + 标识符 + ")(?:\\((" +

		// 为了减少 preFilter 中需要标记化的选择器的数量，prefer arguments:
		// 1. 引用（捕获 3；捕获 4 或捕获 5）
		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*) \")|" +

		// 2. 简单（捕获 6）
		"((?:\\\\.|[^\\\\()[\\]]|" + 属性 + ")*)|" +

		// 3. 其他（捕获 2）
		".*" +
		")\\)|)",

	// 前导和非转义尾随空白，捕获后者之前的一些非空白字符
	rwhitespace = new RegExp( whitespace + "+", "g" ),

	rcomma = new RegExp( "^" + 空格 + "*," + 空格 + "*" ),
	rleadingCombinator = new RegExp( "^" + 空格 + "*([>+~]|" + 空格 + ")" +
		空格 + "*" ),
	rdescend = new RegExp( 空格 + "|>" ),

	rpseudo = new RegExp(伪),
	ridentifier = new RegExp( "^" + identifier + "$" ),

	匹配表达式 = {
		ID: new RegExp( "^#(" + identifier + ")" ),
		CLASS: new RegExp( "^\\.(" + identifier + ")" ),
		TAG: new RegExp( "^(" + 标识符 + "|[*])" ),
		ATTR: new RegExp( "^" + attributes ),
		PSEUDO: new RegExp( "^" + pseudos ),
		孩子：新的正则表达式（
			“^:(仅|第一个|最后一个|第n个|第n个-最后一个）-（子|类型）（？：\\（”+
				空格 + "*(偶|奇|(([+-]|)(\\d*)n|)" + 空格 + "*(?:([+-]|)" +
				空格 + "*(\\d+)|))" + 空格 + "*\\)|)", "i" ),
		bool: new RegExp( "^(?:" + 布尔值 + ")$", "i" ),

		// 用于实现 .is() 的库
		// 我们在 `select` 中使用它来进行 POS 匹配
		needsContext: new RegExp( "^" + 空格 +
			"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + 空格 +
			"*((?:-\\d)?\\d*)" + 空格 + "*\\)|)(?=[^-]|$)", "i" )
	},

	rinputs = /^(?:input|select|textarea|button)$/i,
	rheader = /^h\d$/i,

	// 易于解析/检索的 ID 或 TAG 或 CLASS 选择器
	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,

	rsibling = /[+~]/,

	// CSS 转义
	// https://www.w3.org/TR/CSS21/syndata.html#escaped-characters
	runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + 空格 +
		"?|\\\\([^\\r\\n\\f])", "g" ),
	funescape = 函数（转义，非十六进制）{
		var high = "0x" + escape.slice( 1 ) - 0x10000;

		如果（非十六进制）{

			// 从非十六进制转义序列中去除反斜杠前缀
			返回非十六进制；
		}

		// 用编码的 Unicode 代码点替换十六进制转义序列
		// 支持：IE <=11+
		// 对于 Basic Multilingual Plane (BMP) 之外的值，手动构造一个
		//代理对
		返回高 < 0 ?
			String.fromCharCode( 高 + 0x10000 ) :
			String.fromCharCode( 高 >> 10 | 0xD800, 高 & 0x3FF | 0xDC00 );
	},

	// 用于 iframe；请参阅“setDocument”。
	// 支持：IE 9 - 11+，Edge 12 - 18+
	// 删除函数包装器会导致“权限被拒绝”
	// IE/Edge 中的错误。
	unloadHandler = function() {
		设置文件（）；
	},

	inDisabledFieldset = addCombinator(
		函数（元素）{
			返回 elem.disabled === true && nodeName( elem, "fieldset" );
		},
		{ dir: "parentNode", next: "legend" }
	);

// 支持：仅限 IE <=9
// 访问 document.activeElement 可能会意外抛出
// https://bugs.jquery.com/ticket/13393
函数 safeActiveElement() {
	尝试 {
		返回 document.activeElement；
	} 抓住（错误）{ }
}

// 优化 push.apply(_, NodeList)
尝试 {
	推.申请（
		( arr = slice.call( preferredDoc.childNodes ) ),
		preferredDoc.childNodes
	);

	// 支持：Android <=4.0
	// 静默检测失败的 push.apply
	// eslint-disable-next-line no-unused-expressions
	arr[ preferredDoc.childNodes.length ].nodeType;
} 赶上 ( e ) {
	推 = {
		应用：函数（目标，els）{
			pushNative.apply(target, slice.call(els));
		},
		调用：函数（目标）{
			pushNative.apply( target, slice.call( arguments, 1 ) );
		}
	};
}

函数查找（选择器、上下文、结果、种子）{
	var m, i, elem, nid, match, groups, newSelector,
		newContext = context && context.ownerDocument,

		// nodeType 默认为 9，因为上下文默认为 document
		节点类型 = 上下文？context.nodeType : 9;

	结果=结果|| [];

	// 从具有无效选择器或上下文的调用中提前返回
	如果（类型选择器！==“字符串”||！选择器||
		节点类型 !== 1 && 节点类型 !== 9 && 节点类型 !== 11 ) {

		返回结果；
	}

	// 尝试在 HTML 文档中简化查找操作（相对于过滤器）
	如果（！种子）{
		设置文档（上下文）；
		上下文=上下文|| 文档;

		如果 ( documentIsHTML ) {

			// 如果选择器足够简单，尝试使用“get*By*”DOM 方法
			//（DocumentFragment 上下文除外，其中的方法不存在）
			if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {

				// ID选择器
				如果 ( ( m = 匹配 [ 1 ] ) ) {

					// 文档上下文
					如果（节点类型=== 9）{
						如果（（elem = context.getElementById（m）））{

							// 支持：仅 IE 9
							// getElementById 可以通过名称而不是 ID 来匹配元素
							如果 (elem.id === m) {
								push.call( 结果, elem );
								返回结果；
							}
						} 别的 {
							返回结果；
						}

					// 元素上下文
					} 别的 {

						// 支持：仅 IE 9
						// getElementById 可以通过名称而不是 ID 来匹配元素
						如果 (newContext && (elem = newContext.getElementById(m)) &&
							查找包含（上下文，元素）&&
							elem.id === m ) {

							push.call( 结果, elem );
							返回结果；
						}
					}

				// 类型选择器
				}否则如果（匹配[2]）{
					push.apply( 结果, context.getElementsByTagName( 选择器 ) );
					返回结果；

				// 类选择器
				} else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) {
					push.apply( 结果, context.getElementsByClassName( m ) );
					返回结果；
				}
			}

			// 利用 querySelectorAll
			if ( !nonnativeSelectorCache[ 选择器 + " " ] &&
				( !rbuggyQSA || !rbuggyQSA.test( 选择器 ) ) ) {

				newSelector = 选择器；
				newContext = 上下文；

				// qSA 在评估子或时考虑作用域根之外的元素
				// 后代组合器，这不是我们想要的。
				// 在这种情况下，我们通过在
				// 带有引用范围上下文的 ID 选择器的列表。
				// 当使用前导组合器时，也必须使用该技术
				// querySelectorAll 无法识别这样的选择器。
				// 感谢 Andrew Dupont 提供的这项技术。
				如果（节点类型=== 1 &&
					( rdescend.test( 选择器 ) || rleadingCombinator.test( 选择器 ) ) ) {

					// 扩展兄弟选择器的上下文
					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
						语境;

					// 我们可以使用 :scope 而不是 ID hack 如果浏览器
					// 支持它 & 如果我们不改变上下文。
					// 支持：IE 11+、Edge 17 - 18+
					// IE/Edge 有时会在以下情况下抛出“权限被拒绝”错误
					// 严格比较两个文档；浅比较工作。
					// eslint-disable-next-line eqeqeq
					如果（newContext！=上下文||！support.scope）{

						// 捕获上下文 ID，必要时首先设置它
						如果 ( ( nid = context.getAttribute( "id" ) ) ) {
							nid = jQuery.escapeSelector(nid);
						} 别的 {
							context.setAttribute( "id", ( nid = expando ) );
						}
					}

					// 为列表中的每个选择器添加前缀
					groups = tokenize( 选择器 );
					i = groups.length;
					当我 -  ） {
						组[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
							toSelector(组[我]);
					}
					newSelector = groups.join(",");
				}

				尝试 {
					push.apply( 结果，
						newContext.querySelectorAll( 新选择器 )
					);
					返回结果；
				} 赶上（qsaError）{
					nonnativeSelectorCache（选择器，真）；
				} 最后 {
					如果（nid === 展开）{
						context.removeAttribute( "id" );
					}
				}
			}
		}
	}

	// 所有其他人
	返回 select( selector.replace( rtrimCSS, "$1" ), context, results, seed );
}

/**
 * 创建有限大小的键值缓存
 * @returns {function(string, object)} 在使用
 * 属性名称（空格后缀）字符串和（如果缓存大于 Expr.cacheLength）
 * 删除最旧的条目
 */
函数 createCache() {
	变种键= [];

	函数缓存（键，值）{

		// 使用 (key + " ") 避免与原生原型属性发生冲突
		//（参见 https://github.com/jquery/sizzle/issues/157）
		if ( keys.push( key + " " ) > Expr.cacheLength ) {

			// 只保留最近的条目
			删除缓存[ keys.shift() ];
		}
		返回（缓存[键+“”] =值）;
	}
	返回缓存；
}

/**
 * 标记一个函数供 jQuery 选择器模块特殊使用
 * @param {Function} fn 标记的函数
 */
函数标记函数（fn）{
	fn[ expando ] = true;
	返回 fn；
}

/**
 * 支持使用元素进行测试
 * @param {Function} fn 传递创建的元素并返回布尔结果
 */
函数断言（fn）{
	var el = document.createElement( "fieldset" );

	尝试 {
		返回!!fn( el );
	} 赶上 ( e ) {
		返回假；
	} 最后 {

		// 默认从其父级移除
		如果（el.parentNode）{
			el.parentNode.removeChild( el );
		}

		// 在IE中释放内存
		埃尔=空；
	}
}

/**
 * 返回用于输入类型的伪函数
 * @param {String} 类型
 */
函数 createInputPseudo(类型){
	返回函数（元素）{
		return nodeName( elem, "input" ) && elem.type === 类型;
	};
}

/**
 * 返回一个用于按钮的伪函数
 * @param {String} 类型
 */
函数 createButtonPseudo（类型）{
	返回函数（元素）{
		返回（节点名（元素，“输入”）||节点名（元素，“按钮”））&&
			elem.type === 类型；
	};
}

/**
 * 返回一个函数以伪造为 :enabled/:disabled
 * @param {Boolean} disabled true for :disabled; 错误的：启用
 */
函数 createDisabledPseudo（已禁用）{

	// 已知 :​​disabled 误报：fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
	返回函数（元素）{

		// 只有某些元素可以匹配 :enabled 或 :disabled
		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
		如果（元素中的“表单”）{

			// 检查相关非禁用元素的继承禁用：
			// * 在禁用的字段集中列出与表单相关的元素
			// https://html.spec.whatwg.org/multipage/forms.html#category-listed
			// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
			// * 禁用的 optgroup 中的选项元素
			// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
			// 所有这些元素都有一个“form”属性。
			如果（elem.parentNode && elem.disabled === false）{

				// 如果存在，选项元素将推迟到父 optgroup
				如果（元素中的“标签”）{
					如果（elem.parentNode 中的“标签”）{
						返回 elem.parentNode.disabled === 已禁用；
					} 别的 {
						返回 elem.disabled === 已禁用；
					}
				}

				// 支持：IE 6 - 11+
				// 使用 isDisabled 快捷属性检查禁用的字段集祖先
				返回 elem.isDisabled === 禁用 ||

					// 没有isDisabled的地方，手动检查
					elem.isDisabled !== !disabled &&
						inDisabledFieldset( elem ) === 已禁用；
			}

			返回 elem.disabled === 已禁用；

		// 在信任 disabled 属性之前尝试筛选出不能被禁用的元素。
		// 一些受害者被我们的网络（标签、图例、菜单、轨道）捕获，但它不应该
		// 甚至存在于它们之上，更不用说具有布尔值了。
		} else if（元素中的“标签”）{
			返回 elem.disabled === 已禁用；
		}

		// 其余元素既不是 :enabled 也不是 :disabled
		返回假；
	};
}

/**
 * 返回一个函数以在伪函数中用于位置
 * @param {函数} fn
 */
函数 createPositionalPseudo( fn ) {
	返回 markFunction(函数(参数){
		参数 = + 参数；
		返回 markFunction（函数（种子，匹配）{
			变种j，
				matchIndexes = fn( [], seed.length, argument ),
				i = matchIndexes.length;

			// 匹配在指定索引处找到的元素
			当我 -  ） {
				如果（种子[（j = matchIndexes[i]）]）{
					seed[j] = !( matches[j] = seed[j]);
				}
			}
		});
	});
}

/**
 * 检查节点作为 jQuery 选择器上下文的有效性
 * @param {Element|Object=} 上下文
 * @returns {Element|Object|Boolean} 输入节点如果可接受，否则为假值
 */
函数 testContext(上下文){
	返回上下文 && typeof context.getElementsByTagName !== "undefined" && context;
}

/**
 * 根据当前文档设置一次文档相关变量
 * @param {Element|Object} [node] 用于设置文档的元素或文档对象
 * @returns {Object} 返回当前文档
 */
函数 setDocument（节点）{
	变种子窗口，
		文档=节点？节点.ownerDocument || 节点：首选文档；

	// 如果 doc 无效或已被选中，则提前返回
	// 支持：IE 11+、Edge 17 - 18+
	// IE/Edge 在严格比较时有时会抛出“权限被拒绝”错误
	// 两个文档；浅比较工作。
	// eslint-disable-next-line eqeqeq
	if ( doc == 文档 || doc.nodeType !== 9 || !doc.documentElement ) {
		返回文件；
	}

	// 更新全局变量
	文档 = 文档；
	documentElement = document.documentElement;
	documentIsHTML = !jQuery.isXMLDoc(文档);

	// 支持：仅限 iOS 7，IE 9 - 11+
	// 旧版浏览器不支持无前缀的 `matches`。
	matches = documentElement.matches ||
		文档元素.webkitMatchesSelector ||
		文档元素.msMatchesSelector；

	// 支持：IE 9 - 11+，Edge 12 - 18+
	// 卸载后访问 iframe 文档会引发“权限被拒绝”错误（请参阅 trac-13936）
	// 支持：IE 11+、Edge 17 - 18+
	// IE/Edge 在严格比较时有时会抛出“权限被拒绝”错误
	// 两个文档；浅比较工作。
	// eslint-disable-next-line eqeqeq
	if ( preferredDoc != 文档 &&
		( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {

		// 支持：IE 9 - 11+，Edge 12 - 18+
		subWindow.addEventListener( "卸载", unloadHandler );
	}

	// 支持：IE <10
	// 检查 getElementById 是否按名称返回元素
	// 损坏的 getElementById 方法不会获取以编程方式设置的名称，
	// 所以使用迂回的 getElementsByName 测试
	support.getById = assert(函数(el){
		documentElement.appendChild( el ).id = jQuery.expando;
		返回 !document.getElementsByName ||
			!document.getElementsByName(jQuery.expando).length;
	});

	// 支持：仅 IE 9
	// 检查是否可以执行 matchesSelector
	// 在断开连接的节点上。
	support.disconnectedMatch = assert(函数(el){
		返回 matches.call( el, "*" );
	});

	// 支持：IE 9 - 11+，Edge 12 - 18+
	// IE/Edge 不支持 :scope 伪类。
	支持范围=断言（函数（）{
		返回 document.querySelectorAll( ":scope" );
	});

	// 支持：仅限 Chrome 105 - 111，仅限 Safari 15.4 - 16.3
	// 确保 `:has()` 参数被无情地解析。
	// 我们在测试中包含 `*` 以检测有缺陷的实现
	// _selectively_ 宽容（特别是当列表至少包括
	// 一个有效的选择器）。
	// 请注意，我们将完全不支持 `:has()` 视为完全不支持
	// 符合规范的支持，这很好，因为在这种情况下使用了 `:has()`
	// 环境将在 qSA 路径中失败并回退到 jQuery 遍历
	// 反正。
	support.cssHas = assert(函数(){
		尝试 {
			document.querySelector( ":has(*,:jqfake)" );
			返回假；
		} 赶上 ( e ) {
			返回真；
		}
	});

	// ID 过滤和查找
	如果（支持.getById）{
		Expr.filter.ID = function(id){
			var attrId = id.replace( runescape, funescape );
			返回函数（元素）{
				返回 elem.getAttribute( "id" ) === attrId;
			};
		};
		Expr.find.ID = function(id, context) {
			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
				var elem = context.getElementById( id );
				返回元素？[元素]：[]；
			}
		};
	} 别的 {
		Expr.filter.ID = function(id){
			var attrId = id.replace( runescape, funescape );
			返回函数（元素）{
				var node = typeof elem.getAttributeNode !== "未定义" &&
					elem.getAttributeNode( "id" );
				返回节点 && node.value === attrId;
			};
		};

		// 支持：仅限 IE 6 - 7
		// getElementById 作为查找快捷方式并不可靠
		Expr.find.ID = function(id, context) {
			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
				可变节点，我，元素，
					elem = context.getElementById( id );

				如果（元素）{

					// 验证id属性
					node = elem.getAttributeNode( "id" );
					如果（节点 && 节点.value === id）{
						返回 [元素];
					}

					// 返回到 getElementsByName
					elems = context.getElementsByName(id);
					我 = 0;
					while ( ( elem = elems[ i++ ] ) ) {
						node = elem.getAttributeNode( "id" );
						如果（节点 && 节点.value === id）{
							返回 [元素];
						}
					}
				}

				返回 [];
			}
		};
	}

	// 标签
	Expr.find.TAG = function(标签,上下文){
		if ( typeof context.getElementsByTagName !== "undefined" ) {
			返回 context.getElementsByTagName( 标签 );

		// DocumentFragment 节点没有 gEBTN
		} 别的 {
			返回 context.querySelectorAll( 标签 );
		}
	};

	// 班级
	Expr.find.CLASS = function( className, context ) {
		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
			返回 context.getElementsByClassName( className );
		}
	};

	/* QSA/匹配选择器
	---------------------------------------------- ------------------ */

	// QSA 和 matchesSelector 支持

	rbuggyQSA = [];

	// 构建 QSA 正则表达式
	// 从 Diego Perini 那里采用的正则表达式策略
	断言（函数（EL）{

		变量输入；

		documentElement.appendChild( el ).innerHTML =
			"<a id='" + expando + "'href='' disabled='disabled'></a>" +
			"<select id='" + expando + "-\r\\' disabled='disabled'>" +
			"<option selected=''></option></select>";

		// 支持：仅限 iOS <=7 - 8
		// 布尔属性和“值”在某些 XML 文档中没有得到正确处理
		如果（！el.querySelectorAll（“[选择]”）。长度）{
			rbuggyQSA.push( "\\[" + 空格 + "*(?:value|" + 布尔值 + ")" );
		}

		// 支持：仅限 iOS <=7 - 8
		如果 (!el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
			rbuggyQSA.push( "~=" );
		}

		// 支持：仅限 iOS 8
		// https://bugs.webkit.org/show_bug.cgi?id=136851
		// 页内 `selector#id sibling-combinator selector` 失败
		如果 (!el.querySelectorAll( "a#" + expando + "+*" ).length ) {
			rbuggyQSA.push( ".#.+[+~]" );
		}

		// 支持：Chrome <=105+，Firefox <=104+，Safari <=15.4+
		// 在某些文档类型中，这些选择器不会在本地工作。
		// 这可能没问题，但为了向后兼容，我们要保持
		// 在 jQuery 3.x 中通过 jQuery 遍历处理它们。
		如果 (!el.querySelectorAll(":checked").length){
			rbuggyQSA.push( ":checked" );
		}

		// 支持：Windows 8 本机应用程序
		// type 和 name 属性在 .innerHTML 赋值期间被限制
		input = document.createElement("输入");
		input.setAttribute( "类型", "隐藏" );
		el.appendChild( input ).setAttribute( "name", "D" );

		// 支持：IE 9 - 11+
		// IE 的 :disabled 选择器不会选取禁用字段集的子项
		// 支持：Chrome <=105+，Firefox <=104+，Safari <=15.4+
		// 在某些文档类型中，这些选择器不会在本地工作。
		// 这可能没问题，但为了向后兼容，我们要保持
		// 在 jQuery 3.x 中通过 jQuery 遍历处理它们。
		documentElement.appendChild(el).disabled = true;
		如果 ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
			rbuggyQSA.push( ":enabled", ":disabled" );
		}

		// 支持：IE 11+、Edge 15 - 18+
		// 在某些情况下，IE 11/Edge 在 `[name='']` 查询中找不到元素。
		// 在选择工作之前向文档添加一个临时属性
		// 围绕这个问题。
		// 有趣的是，IE 10 及更早版本似乎没有问题。
		input = document.createElement("输入");
		input.setAttribute( "姓名", "" );
		el.appendChild( 输入 );
		如果 (!el.querySelectorAll( "[name='']" ).length ) {
			rbuggyQSA.push( "\\[" + 空格 + "*name" + 空格 + "*=" +
				空格 + "*(?:''|\"\")" );
		}
	});

	如果（！support.cssHas）{

		// 支持：Chrome 105 - 110+，Safari 15.4 - 16.3+
		// 我们的常规 `try-catch` 机制无法检测到原生不支持
		// `:has()` 中的伪类（比如 `:has(:contains("Foo"))`）
		// 在将 `:has()` 参数解析为宽容选择器列表的浏览器中。
		// https://drafts.c​​sswg.org/selectors/#relational 现在需要参数
		// 被无情地解析，但浏览器还没有完全调整。
		rbuggyQSA.push( ":has" );
	}

	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );

	/* 排序
	---------------------------------------------- ------------------ */

	// 文件顺序排序
	排序顺序 = 函数（a，b）{

		// 去重标志
		如果（a === b）{
			重复=真；
			返回 0；
		}

		// 如果只有一个输入具有 compareDocumentPosition，则根据方法存在性排序
		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
		如果（比较）{
			返回比较；
		}

		// 如果两个输入属于同一文档，则计算位置
		// 支持：IE 11+、Edge 17 - 18+
		// IE/Edge 在严格比较时有时会抛出“权限被拒绝”错误
		// 两个文档；浅比较工作。
		// eslint-disable-next-line eqeqeq
		比较=（a.ownerDocument || a）==（b.ownerDocument || b）？
			a.compareDocumentPosition( b ) :

			// 否则我们知道它们已断开连接
			1;

		// 断开连接的节点
		如果 ( 比较 & 1 ||
			( !support.sortDetached && b.compareDocumentPosition( a ) === 比较 ) ) {

			// 选择与我们首选文档相关的第一个元素
			// 支持：IE 11+、Edge 17 - 18+
			// IE/Edge 在严格比较时有时会抛出“权限被拒绝”错误
			// 两个文档；浅比较工作。
			// eslint-disable-next-line eqeqeq
			if ( a === 文档 || a.ownerDocument == preferredDoc &&
				find.contains( preferredDoc, a ) ) {
				返回-1；
			}

			// 支持：IE 11+、Edge 17 - 18+
			// IE/Edge 在严格比较时有时会抛出“权限被拒绝”错误
			// 两个文档；浅比较工作。
			// eslint-disable-next-line eqeqeq
			if ( b === 文档 || b.ownerDocument == preferredDoc &&
				find.contains( preferredDoc, b ) ) {
				返回 1；
			}

			// 保持原来的顺序
			返回排序输入？
				( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) ：
				0;
		}

		返回比较 & 4 ？-1：1；
	};

	返回文件；
}

find.matches = function(expr, elements) {
	返回查找（expr，null，null，元素）；
};

find.matchesSelector = function(elem,expr){
	设置文档（元素）；

	如果 ( 文档是 HTML &&
		!nonnativeSelectorCache[ expr + " " ] &&
		( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {

		尝试 {
			var ret = matches.call(elem, expr);

			// IE 9 的 matchesSelector 在断开连接的节点上返回 false
			如果 ( ret || support.disconnectedMatch ||

					// 同样，断开连接的节点被认为在文档中
					// IE 9 中的片段
					elem.document && elem.document.nodeType !== 11 ) {
				返还；
			}
		} 赶上 ( e ) {
			nonnativeSelectorCache(expr, true);
		}
	}

	return find(expr, document, null, [ elem ] ).length > 0;
};

find.contains = function(context, elem) {

	// 如果需要设置文档变量
	// 支持：IE 11+、Edge 17 - 18+
	// IE/Edge 在严格比较时有时会抛出“权限被拒绝”错误
	// 两个文档；浅比较工作。
	// eslint-disable-next-line eqeqeq
	如果（（context.ownerDocument || context）！=文档）{
		设置文档（上下文）；
	}
	返回 jQuery.contains(context, elem);
};


find.attr = 函数（元素，名称）{

	// 如果需要设置文档变量
	// 支持：IE 11+、Edge 17 - 18+
	// IE/Edge 在严格比较时有时会抛出“权限被拒绝”错误
	// 两个文档；浅比较工作。
	// eslint-disable-next-line eqeqeq
	如果（（elem.ownerDocument || elem）！=文档）{
		设置文档（元素）；
	}

	var fn = Expr.attrHandle[ name.toLowerCase() ],

		// 不要被 Object.prototype 属性所迷惑（参见 trac-13807）
		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
			fn（元素，名称，！documentIsHTML）：
			不明确的;

	如果（瓦尔！==未定义）{
		返回值；
	}

	返回 elem.getAttribute( 名称 );
};

find.error = function(味精){
	throw new Error( "语法错误，无法识别的表达式：" + msg );
};

/**
 * 文档排序和删除重复项
 * @param {ArrayLike} 结果
 */
jQuery.uniqueSort = 函数（结果）{
	变量元素，
		重复 = [],
		j = 0,
		我 = 0;

	// 除非我们*知道*我们可以检测到重复项，假设它们存在
	//
	// 支持：Android <=4.0+
	// 检测重复项的测试是不可预测的，所以假设我们不能
	// 依赖于所有没有稳定排序的浏览器中的重复检测。
	hasDuplicate = !support.sortStable;
	sortInput = !support.sortStable && slice.call( 结果, 0 );
	sort.call( 结果, sortOrder );

	如果（重复）{
		while ( ( elem = 结果 [ i++ ] ) ) {
			如果（元素===结果[我]）{
				j = duplicates.push(i);
			}
		}
		而（j--）{
			splice.call( 结果, 重复[ j ], 1 );
		}
	}

	// 排序后清空输入释放对象
	// 请参阅 https://github.com/jquery/sizzle/pull/225
	排序输入=空；

	返回结果；
};

jQuery.fn.uniqueSort = function() {
	返回 this.pushStack(jQuery.uniqueSort(slice.apply(this)));
};

Expr = jQuery.expr = {

	// 可以由用户调整
	缓存长度：50，

	创建伪：markFunction，

	匹配：匹配表达式，

	属性句柄：{}，

	寻找： {}，

	相对的： {
		">": { dir: "parentNode", first: true },
		" ": { dir: "parentNode" },
		"+": { dir: "previousSibling", first: true },
		“〜”：{目录：“previousSibling”}
	},

	前置过滤器：{
		属性：函数（匹配）{
			匹配[ 1 ] = 匹配[ 1 ].replace( runescape, funescape );

			// 将给定值移动到 match[3]，无论是引用还是未引用
			匹配[3]=（匹配[3]||匹配[4]||匹配[5]||“”）
				.replace(runescape, funescape);

			如果（匹配[2]===“~=”）{
				匹配[3]=“”+匹配[3]+“”；
			}

			返回 match.slice( 0, 4 );
		},

		孩子：功能（匹配）{

			/* 来自 matchExpr["CHILD"] 的匹配项
				1 种（仅|nth|...）
				2 什么（孩子|类型）
				3 个参数（偶数|奇数|\d*|\d*n([+-]\d​​+)?|...）
				4 xn+y 参数的 xn 分量 ([+-]?\d*n|)
				5 xn分量的符号
				6 x xn-组件
				7 y 分量的符号
				y 分量的 8 y
			*/
			匹配[ 1 ] = 匹配[ 1 ].toLowerCase();

			if ( 匹配 [ 1 ].slice( 0, 3 ) === "nth" ) {

				// nth-* 需要参数
				如果（！匹配[3]）{
					find.error(匹配[0]);
				}

				// Expr.filter.CHILD 的数字 x 和 y 参数
				// 记住 false/true 分别转换为 0/1
				匹配[ 4 ] = +( 匹配[ 4 ] ?
					匹配[5]+（匹配[6]||1）：
					2 * ( 匹配 [ 3 ] === “偶数” || 匹配 [ 3 ] === “奇数” )
				);
				匹配[5]=+((匹配[7]+匹配[8])||匹配[3]===“奇数”);

			// 其他类型禁止参数
			}否则如果（匹配[3]）{
				find.error(匹配[0]);
			}

			返回匹配；
		},

		伪：函数（匹配）{
			无功过剩，
				未加引号 = !match[6] && match[2];

			如果 ( matchExpr.CHILD.test( match[ 0 ] ) ) {
				返回空值；
			}

			// 按原样接受引用的参数
			如果（匹配[3]）{
				匹配[2]=匹配[4]|| 匹配[ 5 ] || "";

			// 从未引用的参数中去除多余的字符
			} else if ( unquoted && rpseudo.test( unquoted ) &&

				// 从 tokenize 中获取多余的（递归地）
				( excess = tokenize( unquoted, true ) ) &&

				// 前进到下一个右括号
				( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {

				// excess 是一个负指标
				match[0] = match[0].slice(0, excess);
				match[2] = unquoted.slice(0, excess);
			}

			// 仅返回伪过滤器方法所需的捕获（类型和参数）
			返回 match.slice( 0, 3 );
		}
	},

	筛选： {

		标签：函数（节点名称选择器）{
			var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
			返回 nodeNameSelector === "*" ？
				功能（） {
					返回真；
				} :
				函数（元素）{
					返回节点名（元素，预期节点名）；
				};
		},

		类：函数（类名）{
			var pattern = classCache[ className + " " ];

			返回模式 ||
				( pattern = new RegExp( "(^|" + 空格 + ")" + 类名 +
					"(" + 空格 + "|$)" ) ) &&
				类缓存（类名，函数（元素）{
					返回模式.test(
						typeof elem.className === "字符串" && elem.className ||
							typeof elem.getAttribute !== "未定义" &&
								elem.getAttribute( "类" ) ||
							“”
					);
				});
		},

		ATTR: 函数（名称、运算符、校验）{
			返回函数（元素）{
				var result = find.attr(elem, name);

				如果（结果==空）{
					返回运算符 === "!=";
				}
				如果（！运​​算符）{
					返回真；
				}

				结果+=“”；

				如果（运算符===“=”）{
					返回结果 === 检查；
				}
				如果（运算符===“！=”）{
					返回结果 !== 检查；
				}
				如果（运算符===“^=”）{
					返回检查 && result.indexOf(检查) === 0;
				}
				如果（运算符===“*=”）{
					返回检查 && result.indexOf( 检查 ) > -1;
				}
				如果（运算符===“$=”）{
					返回检查 && result.slice( -check.length ) === 检查；
				}
				如果（运算符===“~=”）{
					返回（“”+ result.replace（rwhitespace，“”）+“”）
						.indexOf(检查) > -1;
				}
				如果（运算符===“|=”）{
					返回结果===检查|| result.slice( 0, check.length + 1 ) === 检查 + "-";
				}

				返回假；
			};
		},

		孩子：函数（类型，内容，参数，第一个，最后一个）{
			var simple = type.slice( 0, 3 ) !== "nth",
				forward = type.slice( -4 ) !== "last",
				ofType = what === “类型”；

			返回第一个 === 1 && 最后一个 === 0 ？

				// :nth-*(n) 的快捷方式
				函数（元素）{
					返回!!elem.parentNode;
				} :

				功能（元素，_context，xml）{
					var 缓存，outerCache，节点，nodeIndex，开始，
						dir = simple !== 转发？"nextSibling" : "previousSibling",
						parent = elem.parentNode,
						name = ofType && elem.nodeName.toLowerCase(),
						useCache = !xml && !ofType,
						差异=假；

					如果（父母）{

						// :(first|last|only)-(child|of-type)
						如果（简单）{
							而（目录）{
								节点=元素；
								while ( ( node = node[ dir ] ) ) {
									如果（类型？
										节点名（节点，名称）：
										node.nodeType === 1 ) {

										返回假；
									}
								}

								// :only-* 的反向（如果我们还没有这样做的话）
								start = dir = type === "only" && !start && "nextSibling";
							}
							返回真；
						}

						开始= [前进？parent.firstChild : parent.lastChild ];

						// 非 xml :nth-child(...) 在 `parent` 上存储缓存数据
						如果（转发&& useCache）{

							// 从之前缓存的索引中寻找 `elem`
							outerCache = parent[ 展开] || (父[扩展] = {});
							cache = outerCache[ 类型 ] || [];
							nodeIndex = cache[0] === dirruns && cache[1];
							diff = nodeIndex && 缓存[ 2 ];
							node = nodeIndex && parent.childNodes[ nodeIndex ];

							while ( ( node = ++nodeIndex && node && node[ dir ] ||

								// 回退到从头开始寻找 `elem`
								( diff = nodeIndex = 0 ) || 开始.pop() ) ) {

								// 找到后，在 `parent` 上缓存索引并中断
								如果（node.nodeType === 1 && ++diff && node === elem）{
									outerCache[ 类型 ] = [ dirruns, nodeIndex, diff ];
									休息;
								}
							}

						} 别的 {

							// 如果可用，使用先前缓存的元素索引
							如果（使用缓存）{
								outerCache = elem[ expando ] || ( elem[ expando ] = {} );
								cache = outerCache[ 类型 ] || [];
								nodeIndex = cache[0] === dirruns && cache[1];
								diff = 节点索引；
							}

							// xml:nth-child(...)
							// 或 :nth-last-child(...) 或 :nth(-last)?-of-type(...)
							如果（差异===假）{

								// 使用与上面相同的循环从头开始寻找 `elem`
								while ( ( node = ++nodeIndex && node && node[ dir ] ||
									( diff = nodeIndex = 0 ) || 开始.pop() ) ) {

									如果 ( ( 类型 ?
										节点名（节点，名称）：
										节点.节点类型 === 1 ) &&
										++差异）{

										// 缓存每个遇到的元素的索引
										如果（使用缓存）{
											outerCache = 节点[ expando ] ||
												（节点[展开]={}）；
											outerCache[ 类型 ] = [ dirruns, diff ];
										}

										如果（节点===元素）{
											休息;
										}
									}
								}
							}
						}

						//合并偏移量，然后检查循环大小
						差异-=最后；
						先返回 diff === || ( diff % first === 0 && diff / first >= 0 );
					}
				};
		},

		伪：函数（伪，参数）{

			// 伪类名称不区分大小写
			// https://www.w3.org/TR/selectors/#pseudo-classes
			// 区分大小写的优先级，以防自定义伪类添加大写字母
			// 记住 setFilters 继承自 pseudos
			可变参数，
				fn = Expr.pseudos[伪] || Expr.setFilters[ pseudo.toLowerCase() ] ||
					find.error("不支持的伪：" + 伪);

			// 用户可以使用 createPseudo 来表示
			// 需要参数来创建过滤器函数
			// 就像 jQuery 一样
			如果（fn[展开]）{
				返回 fn(参数);
			}

			// 但保持对旧签名的支持
			如果 ( fn.length > 1 ) {
				args = [ pseudo, pseudo, "", 参数 ];
				返回 Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ？
					markFunction（函数（种子，匹配）{
						变种IDX，
							匹配= fn（种子，参数），
							i = matched.length;
						当我 -  ） {
							idx = indexOf.call( seed, matched[ i ] );
							seed[idx] = !( matches[idx] = matched[i]);
						}
					}）：
					函数（元素）{
						返回 fn(elem, 0, args);
					};
			}

			返回 fn；
		}
	},

	伪：{

		// 潜在的复杂伪
		不是：markFunction（函数（选择器）{

			// 修剪传递给编译的选择器
			// 避免处理前导和尾随
			// 空格作为组合子
			变量输入 = [],
				结果 = [],
				matcher = compile( selector.replace( rtrimCSS, "$1" ) );

			返回匹配器[展开]？
				markFunction（函数（种子，匹配，_context，xml）{
					变量元素，
						不匹配=匹配器（种子，空，XML，[]），
						i = seed.length;

					// 匹配 `matcher` 不匹配的元素
					当我 -  ） {
						如果 ( ( elem = 不匹配 [ i ] ) ) {
							seed[i] = !( matches[i] = elem);
						}
					}
				}）：
				功能（元素，_context，xml）{
					输入[0]=元素；
					匹配器（输入、空、xml、结果）；

					// 不保留元素
					//（参见 https://github.com/jquery/sizzle/issues/299）
					输入[0]=空；
					返回 !results.pop();
				};
		}),

		有：markFunction（函数（选择器）{
			返回函数（元素）{
				返回查找（选择器，元素）。长度> 0；
			};
		}),

		包含：markFunction（函数（文本）{
			text = text.replace( runescape, funescape );
			返回函数（元素）{
				return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1;
			};
		}),

		// "元素是否由 :lang() 选择器表示
		// 仅基于元素的语言值
		// 等于标识符 C，
		// 或以标识符 C 开头，紧接着是“-”。
		// C 与元素的语言值的匹配不区分大小写。
		// 标识符 C 不必是有效的语言名称。”
		// https://www.w3.org/TR/selectors/#lang-pseudo
		朗：markFunction（函数（朗）{

			// lang 值必须是一个有效的标识符
			如果（！ridentifier.test（lang ||“”））{
				find.error( "不支持的语言: " + lang );
			}
			lang = lang.replace(runescape, funescape).toLowerCase();
			返回函数（元素）{
				变量元素；
				做 {
					如果 ( ( elemLang = documentIsHTML ?
						元素.lang :
						elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {

						elemLang = elemLang.toLowerCase();
						返回 elemLang === 语言 || elemLang.indexOf( lang + "-" ) === 0;
					}
				} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
				返回假；
			};
		}),

		// 各种各样的
		目标：函数（元素）{
			var hash = window.location && window.location.hash;
			返回散列 && hash.slice( 1 ) === elem.id;
		},

		根：函数（元素）{
			返回元素 === 文档元素；
		},

		焦点：函数（元素）{
			返回 elem === safeActiveElement() &&
				文档.hasFocus() &&
				!!( elem.type || elem.href || ~elem.tabIndex );
		},

		// 布尔属性
		启用：createDisabledPseudo( false ),
		禁用：createDisabledPseudo( true )，

		检查：函数（元素）{

			// 在 CSS3 中，:checked 应该返回选中和选中的元素
			// https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
			返回（nodeName（elem，“输入”）&&!!elem.checked）||
				( nodeName( elem, "option" ) && !!elem.selected );
		},

		选择：函数（元素）{

			// 支持：IE <=11+
			// 访问 selectedIndex 属性
			// 强制浏览器将默认选项视为
			// 在 optgroup 中选择。
			如果（elem.parentNode）{
				// eslint-disable-next-line no-unused-expressions
				elem.parentNode.selectedIndex;
			}

			返回 elem.selected === true;
		},

		// 内容
		空：函数（元素）{

			// https://www.w3.org/TR/selectors/#empty-pseudo
			// :empty 被元素 (1) 或内容节点否定 (text: 3; cdata: 4; entity ref: 5),
			// 但不是其他人（注释：8；处理指令：7；等）
			// nodeType < 6 有效，因为属性 (2) 不作为子项出现
			对于（elem = elem.firstChild；elem；elem = elem.nextSibling）{
				如果 (elem.nodeType < 6) {
					返回假；
				}
			}
			返回真；
		},

		父母：功能（元素）{
			返回 !Expr.pseudos.empty( elem );
		},

		// 元素/输入类型
		标头：函数（元素）{
			返回 rheader.test(elem.nodeName);
		},

		输入：函数（元素）{
			返回 rinputs.test( elem.nodeName );
		},

		按钮：功能（元素）{
			return nodeName( elem, "input" ) && elem.type === "按钮" ||
				节点名（元素，“按钮”）；
		},

		文本：函数（元素）{
			变量属性；
			return nodeName( elem, "input" ) && elem.type === "文本" &&

				// 支持：仅限 IE <10
				// 出现新的 HTML5 属性值（例如，“search”）
				// 使用 elem.type === "text"
				( ( attr = elem.getAttribute( "type" ) ) == null ||
					attr.toLowerCase() === "文本" );
		},

		// 集合中的位置
		第一：createPositionalPseudo( function() {
			返回[0]；
		}),

		最后：createPositionalPseudo（函数（_matchIndexes，长度）{
			返回 [ 长度 - 1 ];
		}),

		eq：createPositionalPseudo（函数（_matchIndexes，长度，参数）{
			返回 [ 参数 < 0 ? 参数 + 长度：参数]；
		}),

		even: createPositionalPseudo( function( matchIndexes, length ) {
			变种我= 0;
			对于（；我<长度；我+=2）{
				matchIndexes.push(i);
			}
			返回匹配索引；
		}),

		奇数：createPositionalPseudo（函数（matchIndexes，长度）{
			变种我= 1;
			对于（；我<长度；我+=2）{
				matchIndexes.push(i);
			}
			返回匹配索引；
		}),

		lt: createPositionalPseudo( function( matchIndexes, length, argument ) {
			变量我；

			如果（参数<0）{
				i = 参数 + 长度；
			}否则如果（参数>长度）{
				我 = 长度；
			} 别的 {
				我=参数；
			}

			对于 ( ; --i >= 0; ) {
				matchIndexes.push(i);
			}
			返回匹配索引；
		}),

		gt：createPositionalPseudo（函数（matchIndexes，长度，参数）{
			var i = 参数 < 0 ? 参数 + 长度：参数；
			对于 ( ; ++i < 长度; ) {
				matchIndexes.push(i);
			}
			返回匹配索引；
		})
	}
};

Expr.pseudos.nth = Expr.pseudos.eq;

// 添加按钮/输入类型伪
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
	Expr.pseudos[ i ] = createInputPseudo( i );
}
对于（我在{提交：真，重置：真}）{
	Expr.pseudos[ i ] = createButtonPseudo( i );
}

// 用于创建新的 setFilters 的简单 API
函数 setFilters() {}
setFilters.prototype = Expr.filters = Expr.pseudos;
Expr.setFilters = new setFilters();

函数标记化（选择器，parseOnly）{
	var 匹配，匹配，标记，类型，
		到目前为止，组，preFilters，
		缓存 = tokenCache[ 选择器 + " " ];

	如果（缓存）{
		返回仅解析？0 : 缓存.slice( 0 );
	}

	至此=选择器；
	组 = [];
	preFilters = Expr.preFilter;

	而（到目前为止）{

		//逗号和第一次运行
		如果（！匹配||（匹配= rcomma.exec（到目前为止）））{
			如果（匹配）{

				// 不要将尾随逗号视为有效
				soFar = soFar.slice(匹配[0].length)|| 迄今为止;
			}
			groups.push( ( tokens = [] ) );
		}

		匹配=假；

		// 组合子
		如果 ( ( match = rleadingCombinator.exec ( soFar ) ) ) {
			匹配 = match.shift();
			tokens.push({
				值：匹配，

				// 将后代组合器转换为空格
				类型：匹配[ 0 ].replace( rtrimCSS, " " )
			});
			soFar = soFar.slice(匹配长度);
		}

		// 过滤器
		for ( 输入 Expr.filter ) {
			if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
				( match = preFilters[ 类型 ]( match ) ) ) ) {
				匹配 = match.shift();
				tokens.push({
					值：匹配，
					类型：类型，
					比赛：比赛
				});
				soFar = soFar.slice(匹配长度);
			}
		}

		如果（！匹配）{
			休息;
		}
	}

	// 返回无效超出部分的长度
	// 如果我们只是解析
	// 否则，抛出错误或返回标记
	如果（仅解析）{
		返回 soFar.length；
	}

	到目前为止返回？
		查找错误（选择器）：

		// 缓存令牌
		tokenCache（选择器，组）.slice（0）；
}

函数 toSelector（令牌）{
	变种我= 0，
		len = tokens.length,
		选择器 = "";
	对于（；我 < 长度；我++）{
		选择器 += tokens[ i ].value;
	}
	返回选择器；
}

函数 addCombinator（匹配器、组合器、基数）{
	var dir = combinator.dir,
		skip = combinator.next,
		键=跳过|| 目录，
		checkNonElements = base && key === "parentNode",
		doneName = done++;

	返回 combinator.first ？

		// 检查最近的祖先/前面的元素
		函数（元素，上下文，xml）{
			while ( ( elem = elem[ dir ] ) ) {
				如果（elem.nodeType === 1 || checkNonElements）{
					返回匹配器（元素、上下文、xml）；
				}
			}
			返回假；
		} :

		// 检查所有祖先/前面的元素
		函数（元素，上下文，xml）{
			var oldCache, outerCache,
				newCache = [ dirruns, doneName ];

			// 我们不能在 XML 节点上设置任意数据，因此它们无法从组合器缓存中获益
			如果（XML）{
				while ( ( elem = elem[ dir ] ) ) {
					如果（elem.nodeType === 1 || checkNonElements）{
						如果（匹配器（元素，上下文，xml））{
							返回真；
						}
					}
				}
			} 别的 {
				while ( ( elem = elem[ dir ] ) ) {
					如果（elem.nodeType === 1 || checkNonElements）{
						outerCache = elem[ expando ] || ( elem[ expando ] = {} );

						如果（跳过&&节点名（elem，跳过））{
							elem = elem[ 目录 ] || 元素;
						} else if ( ( oldCache = outerCache[ key ] ) &&
							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {

							// 分配给 newCache，以便结果反向传播到之前的元素
							返回 (newCache[2] = oldCache[2]);
						} 别的 {

							// 重用 newcache 因此结果反向传播到之前的元素
							outerCache[ key ] = newCache;

							// 匹配意味着我们完成了；失败意味着我们必须继续检查
							if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
								返回真；
							}
						}
					}
				}
			}
			返回假；
		};
}

函数元素匹配器（匹配器）{
	返回 matchers.length > 1 ？
		函数（元素，上下文，xml）{
			var i = matchers.length;
			当我 -  ） {
				如果 ( !matchers[ i ]( elem, context, xml ) ) {
					返回假；
				}
			}
			返回真；
		} :
		匹配器[0]；
}

函数 multipleContexts（选择器、上下文、结果）{
	变种我= 0，
		len = contexts.length;
	对于（；我 < 长度；我++）{
		查找（选择器，上下文[我]，结果）；
	}
	返回结果；
}

函数压缩（无与伦比，地图，过滤器，上下文，xml）{
	变量元素，
		新的不匹配 = [],
		我 = 0,
		len = unmatched.length,
		映射=映射！=空；

	对于（；我 < 长度；我++）{
		如果 ( ( elem = 不匹配 [ i ] ) ) {
			如果 (!filter || filter(elem, context, xml) ) {
				newUnmatched.push(elem);
				如果（映射）{
					map.push(i);
				}
			}
		}
	}

	返回新的不匹配；
}

function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
	如果（postFilter && !postFilter[expando]）{
		postFilter = setMatcher(postFilter);
	}
	如果（postFinder && !postFinder[expando]）{
		postFinder = setMatcher( postFinder, postSelector );
	}
	返回 markFunction（函数（种子，结果，上下文，xml）{
		var temp, i, elem, matcherOut,
			预映射 = [],
			postMap = [],
			预先存在的 = results.length,

			// 从种子或上下文中获取初始元素
			elems = 种子 ||
				multipleContexts( 选择器 || "*",
					上下文.节点类型？[上下文]：上下文，[]），

			// 预过滤器以获取匹配器输入，保留用于种子结果同步的映射
			matcherIn = preFilter && ( 种子 || !selector ) ?
				压缩（元素、preMap、preFilter、上下文、xml）：
				元素；

		如果（匹配器）{

			// 如果我们有一个 postFinder，或者过滤后的种子，或者非种子 postFilter
			// 或预先存在的结果，
			matcherOut = postFinder || （种子？preFilter：预先存在的 || postFilter）？

				// ...需要中间处理
				[]：

				// ...否则直接使用结果
				结果;

			// 查找主要匹配项
			匹配器（匹配器输入、匹配器输出、上下文、xml）；
		} 别的 {
			匹配器输出 = 匹配器输入；
		}

		// 应用postFilter
		如果（后过滤器）{
			temp = condense(matcherOut, postMap);
			postFilter( temp, [], context, xml );

			// 通过将失败的元素移回 matcherIn 来取消匹配
			i = 临时长度；
			当我 -  ） {
				如果 ( ( elem = temp[ i ] ) ) {
					matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap [ i ] ] = elem );
				}
			}
		}

		如果（种子）{
			如果（postFinder || preFilter）{
				如果（postFinder）{

					// 通过将这个中间体压缩到 postFinder 上下文中来获得最终的 matcherOut
					温度 = [];
					i = matcherOut.length;
					当我 -  ） {
						如果 ( ( elem = matcherOut[ i ] ) ) {

							// 恢复 matcherIn 因为 elem 还不是最终匹配
							temp.push((matcherIn[i] = elem));
						}
					}
					postFinder( null, ( matcherOut = [] ), temp, xml );
				}

				// 将匹配的元素从种子移动到结果以保持它们同步
				i = matcherOut.length;
				当我 -  ） {
					如果 ( ( elem = matcherOut[ i ] ) &&
						( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) {

						seed[temp] = !(results[temp] = elem);
					}
				}
			}

		// 将元素添加到结果中，如果已定义则通过 postFinder
		} 别的 {
			matcherOut =压缩（
				matcherOut === 结果 ?
					matcherOut.splice( preexisting, matcherOut.length ) :
					匹配器输出
			);
			如果（postFinder）{
				postFinder（空，结果，matcherOut，xml）；
			} 别的 {
				push.apply( 结果, matcherOut );
			}
		}
	});
}

函数 matcherFromTokens（令牌）{
	var checkContext，匹配器，j，
		len = tokens.length,
		leadingRelative = Expr.relative[ tokens[ 0 ].type ],
		implicitRelative = leadingRelative || Expr.relative[ " " ],
		我 = leadingRelative ? 1 : 0,

		// 基础匹配器确保元素可以从顶级上下文访问
		matchContext = addCombinator(函数(elem){
			返回 elem === checkContext；
		}, implicitRelative, 真),
		matchAnyContext = addCombinator(函数(elem){
			返回 indexOf.call(checkContext, elem) > -1;
		}, implicitRelative, 真),
		匹配器= [函数（元素，上下文，xml）{

			// 支持：IE 11+、Edge 17 - 18+
			// IE/Edge 在严格比较时有时会抛出“权限被拒绝”错误
			// 两个文档；浅比较工作。
			// eslint-disable-next-line eqeqeq
			var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || (
				( checkContext = context ).nodeType ？
					matchContext（元素，上下文，xml）：
					matchAnyContext(elem, context, xml));

			// 避免挂在元素上
			//（参见 https://github.com/jquery/sizzle/issues/299）
			检查上下文=空；
			返还；
		} ];

	对于（；我 < 长度；我++）{
		if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
		} 别的 {
			matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );

			// 在看到位置匹配器时返回特殊
			如果（匹配器[展开]）{

				// 找到下一个相对运算符（如果有的话）以进行正确处理
				j = ++i;
				对于 ( ; j < len; j++ ) {
					if ( Expr.relative[ tokens[ j ].type ] ) {
						休息;
					}
				}
				返回设置匹配器（
					i > 1 && elementMatcher(匹配器),
					我 > 1 && toSelector(

						// 如果前面的标记是后代组合子，则插入一个隐式的任意元素 `*`
						tokens.slice(0, i - 1)
							.concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" } )
					).replace( rtrimCSS, "$1" ),
					匹配器，
					i < j && matcherFromTokens( tokens.slice( i, j ) ),
					j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
					j < len && toSelector( 标记 )
				);
			}
			matchers.push(匹配器);
		}
	}

	返回元素匹配器（匹配器）；
}

函数 matcherFromGroupMatchers( elementMatchers, setMatchers ) {
	var bySet = setMatchers.length > 0,
		byElement = elementMatchers.length > 0,
		superMatcher = function(seed, context, xml, results, outermost) {
			var elem, j, 匹配器,
				匹配计数 = 0,
				我 = "0",
				不匹配 = 种子 && [],
				设置匹配 = [],
				contextBackup = outermostContext,

				// 我们必须始终拥有种子元素或最外层上下文
				elems = 种子 || byElement && Expr.find.TAG("*", outermost ),

				// 使用整数 dirruns 当且仅当这是最外层的匹配器
				dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
				len = elems.length;

			如果（最外层）{

				// 支持：IE 11+、Edge 17 - 18+
				// IE/Edge 在严格比较时有时会抛出“权限被拒绝”错误
				// 两个文档；浅比较工作。
				// eslint-disable-next-line eqeqeq
				outermostContext = 上下文 == 文档 || 上下文 || 最外层；
			}

			// 将直接传递 elementMatchers 的元素添加到结果中
			// 支持：仅限 iOS <=7 - 9
			// 容忍 NodeList 属性（IE: "length"; Safari: <number>）匹配
			// 按 id 的元素。（见 trac-14142）
			for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
				如果（按元素 && 元素）{
					j = 0;

					// 支持：IE 11+、Edge 17 - 18+
					// IE/Edge 在严格比较时有时会抛出“权限被拒绝”错误
					// 两个文档；浅比较工作。
					// eslint-disable-next-line eqeqeq
					如果（！context && elem.ownerDocument！=文档）{
						设置文档（元素）；
						xml = !documentIsHTML;
					}
					while ( ( matcher = elementMatchers[ j++ ] ) ) {
						if ( matcher( elem, context || document, xml ) ) {
							push.call( 结果, elem );
							休息;
						}
					}
					如果（最外层）{
						dirruns = dirrunsUnique;
					}
				}

				// 为设置过滤器跟踪不匹配的元素
				如果（按集）{

					// 他们将遍历所有可能的匹配器
					如果 ( ( elem = !matcher && elem ) ) {
						匹配计数--;
					}

					// 为每个元素加长数组，无论匹配与否
					如果（种子）{
						unmatched.push(elem);
					}
				}
			}

			// `i` 现在是上面访问过的元素的计数，并将其添加到 `matchedCount`
			// 使后者非负。
			匹配计数+=我；

			// 将设置过滤器应用于不匹配的元素
			// 注意：如果没有不匹配的元素（即 `matchedCount`
			// 等于 `i`)，除非我们没有访问上面循环中的_any_元素，因为我们有
			// 没有元素匹配器，也没有种子。
			// 递增初始字符串“0” `i` 允许 `i` 仅在该字符串中保留为字符串
			// 大小写，这将导致“00”`matchedCount` 不同于 `i` 但也是
			// 数值为零。
			if ( bySet && i !== matchedCount ) {
				j = 0;
				while ( ( matcher = setMatchers[ j++ ] ) ) {
					匹配器（不匹配，setMatched，上下文，xml）；
				}

				如果（种子）{

					// 重新整合元素匹配以消除排序的需要
					如果（匹配计数 > 0）{
						当我 -  ） {
							如果（！（不匹配[我]||设置匹配[我]））{
								setMatched[i] = pop.call(results);
							}
						}
					}

					// 丢弃索引占位符值以仅获取实际匹配项
					setMatched = condense( setMatched );
				}

				// 将匹配项添加到结果
				push.apply( 结果, setMatched );

				// 无子集匹配多个成功的匹配器规定排序
				if ( 最外层 && !seed && setMatched.length > 0 &&
					( matchedCount + setMatchers.length ) > 1 ) {

					jQuery.uniqueSort( 结果 );
				}
			}

			// 覆盖嵌套匹配器对全局变量的操作
			如果（最外层）{
				dirruns = dirrunsUnique;
				outermostContext = contextBackup;
			}

			返回无与伦比；
		};

	按集合返回？
		标记函数（超级匹配器）：
		超级匹配器；
}

function compile( selector, match /* 仅供内部使用 */ ) {
	变量我，
		setMatchers = [],
		元素匹配器 = [],
		cached = compilerCache[ 选择器 + " " ];

	如果（！缓存）{

		// 生成可用于检查每个元素的递归函数的函数
		如果（！匹配）{
			match = tokenize( 选择器 );
		}
		i = 匹配长度；
		当我 -  ） {
			缓存 = matcherFromTokens(匹配[我]);
			如果（缓存[扩展]）{
				setMatchers.push(缓存);
			} 别的 {
				elementMatchers.push（缓存）；
			}
		}

		// 缓存编译后的函数
		缓存 = compilerCache( 选择器,
			matcherFromGroupMatchers( elementMatchers, setMatchers ) );

		// 保存选择器和分词
		cached.selector = 选择器；
	}
	返回缓存；
}

/**
 * 与 jQuery 编译后一起使用的低级选择函数
 * 选择器函数
 * @param {String|Function} selector 一个选择器或者一个预编译的
 * 使用 jQuery 选择器编译构建的选择器函数
 * @param {Element} 上下文
 * @param {数组} [结果]
 * @param {Array} [seed] 要匹配的一组元素
 */
函数选择（选择器，上下文，结果，种子）{
	var i, tokens, token, type, find,
		compiled = typeof selector === "function" && 选择器,
		match = !seed && tokenize( ( selector = compiled.selector || selector ) );

	结果=结果|| [];

	// 如果列表中只有一个选择器且没有种子，则尽量减少操作
	//（后者保证了我们的上下文）
	如果（匹配长度=== 1）{

		// 如果前导复合选择器是一个 ID，则减少上下文
		tokens = match[0] = match[0].slice(0);
		如果 ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {

			context = ( Expr.find.ID(
				token.matches[0].replace(runescape, funescape),
				语境
			) || [] )[ 0 ];
			如果（！上下文）{
				返回结果；

			// 预编译的匹配器仍然会验证祖先，所以加强一个级别
			} else if（已编译）{
				context = context.parentNode;
			}

			选择器 = selector.slice( tokens.shift().value.length );
		}

		// 获取一个种子集用于从右到左匹配
		i = matchExpr.needsContext.test（选择器）？0 : 令牌长度；
		当我 -  ） {
			令牌=令牌[我]；

			// 如果我们命中一个组合器，则中止
			if ( Expr.relative[ ( type = token.type ) ] ) {
				休息;
			}
			if ( ( find = Expr.find[ type ] ) ) {

				// 搜索，扩展前导兄弟组合器的上下文
				如果 ( ( 种子 = 找到 (
					token.matches[0].replace(runescape, funescape),
					rsibling.test(令牌[0].类型)&&
						testContext( 上下文.parentNode ) || 语境
				) ) ) {

					// 如果种子为空或没有令牌剩余，我们可以提前返回
					tokens.splice(i, 1);
					selector = seed.length && toSelector( tokens );
					如果（！选择器）{
						push.apply（结果，种子）；
						返回结果；
					}

					休息;
				}
			}
		}
	}

	// 如果没有提供，编译并执行一个过滤函数
	// 如果我们修改了上面的选择器，则提供 `match` 以避免重新标记
	（编译 || 编译（选择器，匹配））（
		种子，
		语境，
		!documentIsHTML,
		结果，
		上下文 || rsibling.test( 选择器 ) && testContext( context.parentNode ) || 语境
	);
	返回结果；
}

// 一次性任务

// 支持：Android <=4.0 - 4.1+
// 排序稳定性
support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;

// 针对默认文档进行初始化
设置文件（）；

// 支持：Android <=4.0 - 4.1+
// 分离的节点混淆地跟随*彼此*
support.sortDetached = assert(函数(el){

	// 应该返回 1，但返回 4（以下）
	返回 el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
});

jQuery.find = 查找；

// 弃用
jQuery.expr[ ":" ] = jQuery.expr.pseudos;
jQuery.unique = jQuery.uniqueSort;

// 这些一直是私有的，但它们曾经被记录在案
// 作为 Sizzle 的一部分，让我们在 3.x 行中维护它们
// 出于向后兼容的目的。
find.compile = 编译；
查找。选择=选择；
find.setDocument = setDocument;

find.escape = jQuery.escapeSelector;
find.getText = jQuery.text;
find.isXML = jQuery.isXMLDoc;
find.selectors = jQuery.expr;
find.support = jQuery.support;
find.uniqueSort = jQuery.uniqueSort;

	/* eslint 启用 */

} )();


var dir = function(elem, dir, until) {
	var 匹配 = [],
		截断 = 直到 !== 未定义；

	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
		如果 (elem.nodeType === 1) {
			if ( 截断 && jQuery( elem ).is( 直到 ) ) {
				休息;
			}
			matched.push(elem);
		}
	}
	返回匹配；
};


var siblings = function(n, elem){
	变种匹配= [];

	对于（；n；n=n.nextSibling）{
		如果（n.nodeType === 1 && n !== elem）{
			matched.push(n);
		}
	}

	返回匹配；
};


var rneedsContext = jQuery.expr.match.needsContext;

var rsingleTag = ( /^<([az][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>( ?:<\/\1>|)$/i );



// 为 filter 和 not 实现相同的功能
函数winnow（元素，限定词，不）{
	如果（isFunction（限定符））{
		返回 jQuery.grep( 元素, 函数( elem, i ) {
			return !!qualifier.call( elem, i, elem ) !== 不是；
		});
	}

	// 单个元素
	如果（限定符.nodeType）{
		返回 jQuery.grep（元素，函数（元素）{
			return ( elem === qualifier ) !== not;
		});
	}

	// Arraylike of elements (jQuery, arguments, Array)
	如果（类型限定符！==“字符串”）{
		返回 jQuery.grep（元素，函数（元素）{
			return ( indexOf.call( qualifier, elem ) > -1 ) !== 不是；
		});
	}

	// 直接过滤简单和复杂的选择器
	返回 jQuery.filter（限定符，元素，不）；
}

jQuery.filter = function(expr, elems, not) {
	var elem = elems[0];

	如果不 ） {
		expr = ":not(" + expr + ")";
	}

	如果（elems.length === 1 && elem.nodeType === 1）{
		返回 jQuery.find.matchesSelector(elem,expr)？[元素]：[]；
	}

	返回 jQuery.find.matches(expr, jQuery.grep(elems, function(elem){
		返回 elem.nodeType === 1;
	} );
};

jQuery.fn.extend({
	查找：函数（选择器）{
		var i, ret,
			len = this.length,
			自我=这个；

		如果（类型选择器！==“字符串”）{
			返回 this.pushStack( jQuery( 选择器 ).filter( function() {
				对于 ( i = 0; i < len; i++ ) {
					if ( jQuery.contains( self[ i ], this ) ) {
						返回真；
					}
				}
			} );
		}

		ret = this.pushStack([]);

		对于 ( i = 0; i < len; i++ ) {
			jQuery.find( 选择器, self[i], ret);
		}

		返回 len > 1 ？jQuery.uniqueSort( ret ) : ret;
	},
	过滤器：函数（选择器）{
		返回 this.pushStack( winnow( this, 选择器 || [], false ) );
	},
	不是：函数（选择器）{
		返回 this.pushStack( winnow( this, 选择器 || [], true ) );
	},
	是：函数（选择器）{
		返回!!winnow(
			这，

			// 如果这是位置/相对选择器，检查返回集合中的成员资格
			// 因此 $("p:first").is("p:last") 不会为包含两个“p”的文档返回 true。
			选择器类型 === “字符串” && rneedsContext.test( 选择器 ) ?
				jQuery（选择器）：
				选择器 || [],
			错误的
		）。长度;
	}
});


// 初始化一个 jQuery 对象


// 对根 jQuery(document) 的中央引用
变种 rootjQuery,

	// 检查 HTML 字符串的简单方法
	// 通过 location.hash (trac-9521) 将 #id 优先于 <tag> 以避免 XSS
	// 严格的 HTML 识别（trac-11290：必须以 < 开头）
	// 快捷方式简单的#id case for speed
	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,

	init = jQuery.fn.init = function（选择器，上下文，根）{
		var匹配，elem；

		// 句柄：$(""), $(null), $(undefined), $(false)
		如果（！选择器）{
			归还这个；
		}

		// 方法 init() 接受备用 rootjQuery
		// 所以 migrate 可以支持 jQuery.sub (gh-2101)
		根=根|| 根查询；

		// 处理 HTML 字符串
		如果（类型选择器===“字符串”）{
			如果（选择器[0]===“<”&&
				选择器[ selector.length - 1 ] === ">" &&
				选择器.length >= 3 ) {

				// 假设以 <> 开头和结尾的字符串是 HTML 并跳过正则表达式检查
				match = [ null, 选择器, null ];

			} 别的 {
				match = rquickExpr.exec(选择器);
			}

			// 匹配 html 或确保没有为 #id 指定上下文
			如果（匹配&&（匹配[1]||！上下文））{

				// 句柄：$(html) -> $(数组)
				如果（匹配[1]）{
					上下文 = jQuery 的上下文实例？上下文[0]：上下文；

					// 运行脚本的选项对于后向兼容是正确的
					// 如果 parseHTML 不存在，故意抛出错误
					jQuery.merge( 这个, jQuery.parseHTML(
						匹配[ 1 ],
						上下文 && context.nodeType ？上下文.ownerDocument || 上下文：文档，
						真的
					));

					// 句柄：$(html, props)
					如果（rsingleTag.test（匹配[1]）&& jQuery.isPlainObject（上下文））{
						for（在上下文中匹配）{

							// 如果可能，上下文的属性被称为方法
							如果（isFunction（这个[匹配]））{
								这个[匹配](上下文[匹配]);

							// ...否则设置为属性
							} 别的 {
								this.attr(匹配，上下文[匹配]);
							}
						}
					}

					归还这个；

				// 句柄：$(#id)
				} 别的 {
					elem = document.getElementById(匹配[2]);

					如果（元素）{

						// 将元素直接注入到 jQuery 对象中
						这个[ 0 ] =元素；
						这个.length = 1;
					}
					归还这个；
				}

			// 句柄：$(expr, $(...))
			} else if ( !context || context.jquery ) {
				返回（上下文||根）。找到（选择器）；

			// 句柄：$(expr, context)
			//（相当于：$(context).find(expr)
			} 别的 {
				返回 this.constructor(context).find(selector);
			}

		// 句柄：$(DOMElement)
		} else if ( selector.nodeType ) {
			this[ 0 ] = 选择器；
			这个.length = 1;
			归还这个；

		// 句柄：$(函数)
		// 文档就绪的快捷方式
		} else if ( isFunction( 选择器 ) ) {
			返回 root.ready !== undefined ？
				root.ready（选择器）：

				// 如果没有就绪则立即执行
				选择器（jQuery）；
		}

		返回 jQuery.makeArray（选择器，这个）；
	};

// 为 init 函数提供 jQuery 原型以供稍后实例化
init.prototype = jQuery.fn;

// 初始化中心引用
rootjQuery = jQuery(文档);


var rparentsprev = /^(?:parents|prev(?:Until|All))/,

	// 当从唯一集开始时保证产生唯一集的方法
	保证唯一 = {
		孩子们：真的，
		内容：真实，
		下一个：真的，
		上一条：真
	};

jQuery.fn.extend({
	有：功能（目标）{
		var targets = jQuery( target, this ),
			l = 目标.长度；

		返回 this.filter( 函数 () {
			变种我= 0;
			对于（；我<我；我++）{
				if ( jQuery.contains( this, targets[ i ] ) ) {
					返回真；
				}
			}
		});
	},

	最近：功能（选择器，上下文）{
		变种，
			我 = 0,
			l = this.length,
			匹配 = [],
			targets = typeof selectors !== "string" && jQuery( selectors );

		// 位置选择器永远不会匹配，因为没有_selection_上下文
		如果（！rneedsContext.test（选择器））{
			对于（；我<我；我++）{
				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {

					// 总是跳过文档片段
					如果 ( cur.nodeType < 11 && ( 目标 ?
						targets.index( cur ) > -1 :

						// 不要将非元素传递给 jQuery#find
						当前节点类型 === 1 &&
							jQuery.find.matchesSelector(cur, selectors) ) ) {

						matched.push(cur);
						休息;
					}
				}
			}
		}

		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
	},

	// 确定元素在集合中的位置
	索引：函数（元素）{

		// 没有参数，返回父级索引
		如果（！元素）{
			返回（这个[0]&&这个[0].parentNode）？this.first().prevAll().length : -1;
		}

		// 选择器中的索引
		如果（类型元素===“字符串”）{
			返回 indexOf.call(jQuery(elem),this[0]);
		}

		// 定位所需元素的位置
		返回 indexOf.call( 这个，

			// 如果它接收到一个 jQuery 对象，则使用第一个元素
			elem.jquery ？元素[0]：元素
		);
	},

	添加：函数（选择器，上下文）{
		返回这个.pushStack(
			jQuery.uniqueSort(
				jQuery.merge( this.get(), jQuery( 选择器, 上下文 ) )
			)
		);
	},

	addBack：函数（选择器）{
		返回 this.add( 选择器 == null ?
			this.prevObject : this.prevObject.filter( 选择器 )
		);
	}
});

函数兄弟（cur，dir）{
	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
	返回当前；
}

jQuery.each({
	父母：功能（元素）{
		var parent = elem.parentNode;
		返回父级 && parent.nodeType !== 11 ？父母：空；
	},
	父母：功能（元素）{
		return dir( elem, "父节点" );
	},
	parentsUntil: 函数( elem, _i, 直到) {
		return dir( elem, "parentNode", 直到 );
	},
	下一个：函数（元素）{
		返回兄弟姐妹（elem，“nextSibling”）;
	},
	上一个：函数（元素）{
		返回兄弟姐妹（elem，“previousSibling”）;
	},
	nextAll：函数（元素）{
		return dir( elem, "nextSibling" );
	},
	prevAll：函数（元素）{
		return dir( elem, "previousSibling" );
	},
	nextUntil: 函数( elem, _i, 直到) {
		return dir( elem, "nextSibling", 直到);
	},
	prevUntil: 函数( elem, _i, 直到) {
		return dir( elem, "previousSibling", 直到);
	},
	兄弟姐妹：函数（元素）{
		返回兄弟姐妹（（elem.parentNode || {}）.firstChild，elem）;
	},
	孩子们：功能（元素）{
		返回兄弟姐妹（elem.firstChild）；
	},
	内容：函数（元素）{
		如果 ( elem.contentDocument != null &&

			// 支持：IE 11+
			// 没有 `data` 属性的 <object> 元素有一个对象
			// 带有 `null` 原型的 `contentDocument`。
			getProto( elem.contentDocument ) ) {

			返回 elem.contentDocument；
		}

		// 支持：仅限 IE 9 - 11，仅限 iOS 7，仅限 Android 浏览器 <=4.3
		// 在浏览器中将模板元素视为常规元素
		// 不支持。
		如果（节点名（元素，“模板”））{
			elem = elem.content || 元素;
		}

		返回 jQuery.merge([], elem.childNodes);
	}
}, 函数(名称, fn) {
	jQuery.fn[ 名称 ] = 函数（直到，选择器）{
		var matched = jQuery.map(this, fn, until);

		如果（名称.slice（-5）！==“直到”）{
			选择器=直到；
		}

		如果（选择器&&类型选择器===“字符串”）{
			matched = jQuery.filter(选择器,匹配);
		}

		如果（这个。长度> 1）{

			// 去除重复项
			如果（！guaranteedUnique [名称]）{
				jQuery.uniqueSort(匹配);
			}

			// parents* 和 prev-derivatives 的逆序
			如果（rparentsprev.test（名称））{
				matched.reverse();
			}
		}

		返回 this.pushStack(匹配);
	};
});
var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );



// 将字符串格式的选项转换为对象格式的选项
函数 createOptions（选项）{
	变量对象 = {};
	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
		对象[标志] = true；
	});
	返回对象；
}

/*
 * 使用以下参数创建回调列表：
 *
 * options: 一个可选的空格分隔选项列表，将改变如何
 *回调列表行为或更传统的选项对象
 *
 * 默认情况下，回调列表将充当事件回调列表，并且可以
 * 多次“解雇”。
 *
 * 可能的选项：
 *
 * once: 将确保回调列表只能触发一次（如 Deferred）
 *
 * 内存：将跟踪以前的值并调用添加的任何回调
 * 在列表被立即用最新的“记忆”解雇后
 * 值（如延迟）
 *
 * unique: 将确保回调只能添加一次（列表中没有重复）
 *
 * stopOnFalse: 当回调返回 false 时中断调用
 *
 */
jQuery.Callbacks = 函数（选项）{

	// 如果需要，将选项从字符串格式转换为对象格式
	//（我们首先检查缓存）
	选项=类型选项===“字符串”？
		创建选项（选项）：
		jQuery.extend({}, 选项);

	var // 标志以了解列表当前是否正在触发
		射击，

		// 不可忘记列表的最后触发值
		记忆，

		// 标记以了解列表是否已经被触发
		被解雇，

		// 标记以防止触发
		锁定,

		// 实际回调列表
		列表 = [],

		// 可重复列表的执行数据队列
		队列 = [],

		// 当前触发回调的索引（根据需要通过添加/删除进行修改）
		firingIndex = -1,

		// 触发回调
		火=功能（）{

			// 强制单发
			锁定=锁定|| 选项.一次；

			// 为所有挂起的执行执行回调，
			// 尊重 firingIndex 覆盖和运行时更改
			解雇 = 解雇 = 真；
			for ( ; queue.length; firingIndex = -1 ) {
				内存 = queue.shift();
				while ( ++firingIndex < list.length ) {

					// 运行回调并检查提前终止
					如果（列表[firingIndex].apply（内存[0]，内存[1]）===假&&
						options.stopOnFalse ) {

						// 跳转到结束并忘记数据所以 .add 不会重新触发
						firingIndex = list.length;
						内存=假；
					}
				}
			}

			// 如果我们用完了就忘记数据
			如果（！options.memory）{
				内存=假；
			}

			开火=假；

			// 如果我们永远完成了射击，请清理
			如果（锁定）{

				// 如果我们有未来添加调用的数据，请保留一个空列表
				如果（内存）{
					列表 = [];

				// 否则，该对象被花费
				} 别的 {
					列表 = "";
				}
			}
		},

		// 实际回调对象
		自我= {

			// 向列表中添加回调或回调集合
			添加：函数（）{
				如果（列表）{

					// 如果我们有过去运行的记忆，我们应该在添加后触发
					如果（内存&&！开火）{
						firingIndex = list.length - 1;
						queue.push(内存);
					}

					（函数添加（参数）{
						jQuery.each(args, function(_, arg){
							如果（isFunction（arg））{
								如果 (!options.unique || !self.has(arg)){
									list.push(arg);
								}
							} else if ( arg && arg.length && toType( arg ) !== "string" ) {

								// 递归检查
								添加（参数）；
							}
						});
					} )( 参数 );

					如果（内存&&！开火）{
						火（）;
					}
				}
				归还这个；
			},

			// 从列表中删除一个回调
			删除：函数（）{
				jQuery.each（参数，函数（_，arg）{
					变量索引；
					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
						list.splice(索引, 1);

						// 处理触发索引
						如果（索引<= firingIndex）{
							firingIndex--;
						}
					}
				});
				归还这个；
			},

			// 检查给定的回调是否在列表中。
			// 如果没有给出参数，则返回列表是否附加了回调。
			有：函数（fn）{
				返回 fn ？
					jQuery.inArray( fn, list ) > -1 :
					列表长度 > 0;
			},

			// 从列表中删除所有回调
			空：函数（）{
				如果（列表）{
					列表 = [];
				}
				归还这个；
			},

			// 禁用 .fire 和 .add
			// 中止任何当前/未决的执行
			// 清除所有回调和值
			禁用：函数（）{
				锁定=队列= [];
				列表=内存=“”；
				归还这个；
			},
			禁用：功能（）{
				返回！列表；
			},

			// 禁用.fire
			// 也禁用 .add 除非我们有内存（因为它不会有任何效果）
			// 中止任何未决的执行
			锁定：功能（）{
				锁定=队列= [];
				如果（！内存&&！开火）{
					列表=内存=“”；
				}
				归还这个；
			},
			锁定：功能（）{
				返回!!锁定；
			},

			// 使用给定的上下文和参数调用所有回调
			fireWith：函数（上下文，args）{
				如果（！锁定）{
					参数 = 参数 || [];
					args = [ 上下文，args.slice ? args.slice() : 参数];
					queue.push(参数);
					如果（！开火）{
						火（）;
					}
				}
				归还这个；
			},

			// 使用给定的参数调用所有回调
			火：功能（）{
				self.fireWith( 这个, 参数 );
				归还这个；
			},

			// 知道回调是否至少被调用过一次
			解雇：功能（）{
				返回!!被解雇；
			}
		};

	回归自我；
};


功能标识（v）{
	返回 v;
}
功能投掷器（前）{
	扔前;
}

function adoptValue(value, resolve, reject, noValue) {
	变量方法；

	尝试 {

		// 首先检查 promise 方面以授予同步行为特权
		如果（值&& isFunction（（方法= value.promise）））{
			method.call(value).done(resolve).fail(reject);

		// 其他thenables
		} else if ( value && isFunction( ( method = value.then ) ) ) {
			方法调用（值，解决，拒绝）；

		// 其他非thenables
		} 别的 {

			// 通过让 Array#slice 将布尔值 `noValue` 转换为整数来控制 `resolve` 参数：
			// * false: [ 值 ].slice( 0 ) => resolve( 值 )
			// * true: [ 值 ].slice( 1 ) => resolve()
			resolve.apply(undefined, [value].slice(noValue));
		}

	// 对于 Promises/A+，将异常转换为拒绝
	// 因为 jQuery.when 不打开 thenables，我们可以跳过出现在
	// Deferred#then 有条件地抑制拒绝。
	} 赶上（价值）{

		// 支持：仅限 Android 4.0
		// 在没有 .call/.apply 的情况下调用的严格模式函数获取全局对象上下文
		拒绝申请（未定义，[价值]）；
	}
}

jQuery.扩展（{

	延迟：函数（函数）{
		var 元组 = [

				// 动作，添加监听器，回调，
				// ... .then 处理程序，参数索引，[最终状态]
				[ "通知", "进度", jQuery.Callbacks( "内存" ),
					jQuery.Callbacks( "内存" ), 2 ],
				[“解决”，“完成”，jQuery.Callbacks（“一次记忆”），
					jQuery.Callbacks( "一次记忆" ), 0, "已解决" ],
				[“拒绝”，“失败”，jQuery.Callbacks（“一次记忆”），
					jQuery.Callbacks("一次记忆"), 1, "rejected" ]
			],
			状态=“待定”，
			承诺 = {
				状态：函数（）{
					返回状态；
				},
				总是：函数（）{
					deferred.done(arguments).fail(arguments);
					归还这个；
				},
				“捕捉”：函数（fn）{
					返回 promise.then( null, fn );
				},

				// 保留管道以进行反向兼容
				管道：函数（/* fnDone，fnFail，fnProgress */）{
					var fns = 参数；

					返回 jQuery.Deferred(函数(newDefer){
						jQuery.each（元组，函数（_i，元组）{

							// 将元组 (progress, done, fail) 映射到参数 (done, fail, progress)
							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];

							// deferred.progress(function() { 绑定到 newDefer 或 newDefer.notify })
							// deferred.done(function() { 绑定到 newDefer 或 newDefer.resolve })
							// deferred.fail(function() { 绑定到 newDefer 或 newDefer.reject })
							延迟[元组[1]](函数(){
								var returned = fn && fn.apply( this, arguments );
								如果（返回&& isFunction（返回.promise））{
									返回.promise()
										.progress(newDefer.notify)
										.done(newDefer.resolve)
										.fail( newDefer.reject );
								} 别的 {
									newDefer[ tuple[ 0 ] + "With" ](
										这，
										是吗？[返回]：参数
									);
								}
							});
						});
						fns = 空；
					} ）。承诺（）;
				},
				然后：函数（onFulfilled，onRejected，onProgress）{
					变种最大深度= 0;
					函数解析（深度，延迟，处理程序，特殊）{
						返回函数（）{
							那个=这个，
								args = 参数，
								可能抛出=功能（）{
									然后 var 返回；

									// 支持：Promises/A+ section 2.3.3.3.3
									// https://promisesaplus.com/#point-59
									// 忽略双分辨率尝试
									如果（深度 < 最大深度）{
										返回;
									}

									returned = handler.apply( that, args );

									// 支持：Promises/A+ section 2.3.1
									// https://promisesaplus.com/#point-48
									如果（返回=== deferred.promise（））{
										throw new TypeError( "Thenable self-resolution" );
									}

									// 支持：Promises/A+ sections 2.3.3.1, 3.5
									// https://promisesaplus.com/#point-54
									// https://promisesaplus.com/#point-75
									// 只检索一次 `then`
									然后=返回&&

										// 支持：Promises/A+ section 2.3.4
										// https://promisesaplus.com/#point-64
										// 只检查对象和函数的 thenability
										( typeof 返回 === “对象” ||
											typeof 返回 === "函数" ) &&
										返回。然后；

									// 处理返回的 thenable
									如果（isFunction（然后））{

										// 特殊处理器（通知）只是等待解决
										如果（特殊）{
											然后.call(
												回到，
												解决（最大深度，延迟，身份，特殊），
												解决（最大深度，延迟，投掷器，特殊）
											);

										// 普通处理器（解析）也挂钩到进度
										} 别的 {

											// ...并忽略旧的分辨率值
											最大深度++；

											然后.call(
												回到，
												解决（最大深度，延迟，身份，特殊），
												resolve(maxDepth, deferred, Thrower, special),
												解决（最大深度，延迟，身份，
													延迟.notifyWith )
											);
										}

									// 处理所有其他返回值
									} 别的 {

										// 只有替代处理程序传递上下文
										// 和多个值（非规范行为）
										如果（处理程序！==身份）{
											那=未定义；
											参数 = [返回];
										}

										// 处理值
										// 默认进程是 resolve
										( 特殊 || deferred.resolveWith )( 那, args );
									}
								},

								// 只有普通处理器（解析）捕获和拒绝异常
								过程=特殊？
									可能抛出：
									功能（） {
										尝试 {
											可能抛出（）；
										} 赶上 ( e ) {

											如果（jQuery.Deferred.exceptionHook）{
												jQuery.Deferred.exceptionHook( e,
													处理错误）；
											}

											// 支持：Promises/A+ section 2.3.3.3.4.1
											// https://promisesaplus.com/#point-61
											// 忽略解析后异常
											如果（深度 + 1 >= 最大深度）{

												// 只有替代处理程序传递上下文
												// 和多个值（非规范行为）
												如果（处理程序！==投掷器）{
													那=未定义；
													参数 = [ e ];
												}

												deferred.rejectWith(那个, args );
											}
										}
									};

							// 支持：Promises/A+ section 2.3.3.3.1
							// https://promisesaplus.com/#point-57
							// 立即重新解析 promises 以躲避来自
							// 后续错误
							如果（深度）{
								过程（）;
							} 别的 {

								// 调用一个可选的钩子来记录错误，以防出现异常
								// 因为当执行异步时它会丢失
								如果（jQuery.Deferred.getErrorHook）{
									process.error = jQuery.Deferred.getErrorHook();

								// 上面已弃用的别名。顾名思义
								// 返回堆栈，而不是错误实例，jQuery 只是通过
								// 它直接到 `console.warn` 所以两者都可以工作；一个实例
								// 只是更好地与源地图合作。
								} 否则如果（jQuery.Deferred.getStackHook）{
									process.error = jQuery.Deferred.getStackHook();
								}
								window.setTimeout(进程);
							}
						};
					}

					返回 jQuery.Deferred(函数(newDefer){

						// progress_handlers.add( ... )
						元组[0][3].add(
							解决（
								0,
								新延迟，
								isFunction（onProgress）？
									进度：
									身份，
								newDefer.notifyWith
							)
						);

						// fulfilled_handlers.add( ... )
						元组[ 1 ][ 3 ].add(
							解决（
								0,
								新延迟，
								isFunction（onFulfilled）？
									onFulfilled ：
									身份
							)
						);

						// rejected_handlers.add( ... )
						元组[ 2 ][ 3 ].add(
							解决（
								0,
								新延迟，
								isFunction（onRejected）？
									被拒绝：
									投掷者
							)
						);
					} ）。承诺（）;
				},

				// 为这个 deferred 获取一个 promise
				// 如果提供了 obj，则将 promise 方面添加到对象
				承诺：功能（对象）{
					返回 obj ！= null ？jQuery.extend(obj, promise) : 承诺；
				}
			},
			延迟={}；

		// 添加特定于列表的方法
		jQuery.each（元组，函数（我，元组）{
			var 列表 = 元组[ 2 ],
				stateString = tuple[5];

			// promise.progress = list.add
			// promise.done = list.add
			// promise.fail = list.add
			promise[ tuple[ 1 ] ] = list.add;

			// 处理状态
			如果（状态字符串）{
				列表. 添加(
					功能（） {

						// state = "resolved"（即完成）
						//状态=“拒绝”
						状态 = 状态字符串；
					},

					// rejected_callbacks.禁用
					// fulfilled_callbacks.禁用
					元组[ 3 - i ][ 2 ].disable,

					// rejected_handlers.disable
					// fulfilled_handlers.disable
					元组[ 3 - i ][ 3 ].disable,

					// progress_callbacks.lock
					元组[0][2].锁，

					// progress_handlers.lock
					元组[0][3].lock
				);
			}

			// progress_handlers.fire
			// fulfilled_handlers.fire
			// rejected_handlers.fire
			list.add( tuple[ 3 ].fire );

			// deferred.notify = function() { deferred.notifyWith(...) }
			// deferred.resolve = function() { deferred.resolveWith(...) }
			// deferred.reject = function() { deferred.rejectWith(...) }
			延迟[元组[0]]=函数（）{
				延迟[元组[0]+“有”]（这个===延迟？未定义：这个，参数）；
				归还这个；
			};

			// deferred.notifyWith = list.fireWith
			// deferred.resolveWith = list.fireWith
			// deferred.rejectWith = list.fireWith
			延迟[tuple[0]+“With”]=list.fireWith；
		});

		// 让 deferred 成为一个 promise
		promise.promise（延迟）；

		// 如果有的话调用给定的函数
		如果（功能）{
			func.call（延迟，延迟）；
		}

		// 全做完了！
		退货延期；
	},

	// 延迟助手
	何时：函数（单值）{
		变量

			// 未完成下属的计数
			剩余 = arguments.length,

			// 未处理参数的计数
			我 = 剩余，

			// 从属履行数据
			resolveContexts = Array(我),
			resolveValues = slice.call(参数),

			// 主要的 Deferred
			primary = jQuery.Deferred(),

			// 从属回调工厂
			updateFunc = 函数（一世）{
				返回函数（值）{
					resolveContexts[ i ] = 这个；
					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : 值；
					如果（！（--剩余））{
						primary.resolveWith(resolveContexts, resolveValues);
					}
				};
			};

		// 像 Promise.resolve 一样采用单参数和空参数
		如果（剩余 <= 1）{
			adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
				！其余的 ）;

			// 使用 .then() 解包次级 thenables（参见 gh-3000）
			if ( primary.state() === “挂起” ||
				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {

				返回 primary.then();
			}
		}

		// 多个参数像 Promise.all 数组元素一样聚合
		当我 -  ） {
			adoptValue(resolveValues[i], updateFunc(i), primary.reject);
		}

		返回 primary.promise();
	}
});


// 这些通常表明程序员在开发过程中犯了错误，
// 尽快警告它们而不是默认吞下它们。
var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;

// 如果定义了 `jQuery.Deferred.getErrorHook`，则 `asyncError` 是一个错误
// 在异步屏障之前捕获以获取原始错误原因
//否则可能会被隐藏。
jQuery.Deferred.exceptionHook = function(error, asyncError){

	// 支持：仅限 IE 8 - 9
	// 控制台在开发工具打开时存在，这随时可能发生
	如果（window.console && window.console.warn && error && rerrorNames.test（error.name））{
		window.console.warn( "jQuery.Deferred 异常：" + error.message,
			错误堆栈，异步错误）；
	}
};




jQuery.readyException = 函数（错误）{
	window.setTimeout(函数(){
		抛出错误；
	});
};




// 在 DOM 就绪时使用的 deferred
var readyList = jQuery.Deferred();

jQuery.fn.ready = function( fn ) {

	就绪列表
		.then(fn)

		// 将 jQuery.readyException 包装在一个函数中，以便查找
		// 发生在错误处理而不是回调时
		// 登记。
		.catch(函数(错误){
			jQuery.readyException(错误);
		});

	归还这个；
};

jQuery.扩展（{

	// DOM 准备好使用了吗？一旦发生就设置为真。
	就绪：假，

	// 一个计数器，用于跟踪之前要等待的项目数
	// 就绪事件触发。见 trac-6781
	准备等待：1，

	// 当 DOM 准备好时处理
	准备就绪：功能（等待）{

		// 如果有未决的保留或我们已经准备好，则中止
		如果（等待===真？--jQuery.readyWait：jQuery.isReady）{
			返回;
		}

		// 记住 DOM 已经准备好了
		jQuery.isReady = true;

		// 如果正常的 DOM Ready 事件被触发，递减，并在需要时等待
		如果（等待！== true && --jQuery.readyWait > 0）{
			返回;
		}

		// 如果绑定了函数，则执行
		readyList.resolveWith( 文档, [ jQuery ] );
	}
});

jQuery.ready.then = readyList.then;

// 就绪事件处理程序和自我清理方法
功能完成（）{
	document.removeEventListener( "DOMContentLoaded", 完成);
	window.removeEventListener( "load", completed );
	jQuery.ready();
}

// 捕获 $(document).ready() 被调用的情况
// 在浏览器事件已经发生之后。
// 支持：仅限 IE <=9 - 10
// 较旧的 IE 有时会过早地发出“交互”信号
if ( document.readyState === "完成" ||
	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {

	// 异步处理，让脚本有机会延迟就绪
	window.setTimeout(jQuery.ready);

} 别的 {

	// 使用方便的事件回调
	document.addEventListener( "DOMContentLoaded", 完成);

	// 回退到 window.onload，它将始终有效
	window.addEventListener( "load", completed );
}




// 获取和设置集合值的多功能方法
// 如果它是一个函数，则可以选择性地执行该值
var access = function(elems, fn, key, value, chainable, emptyGet, raw) {
	变种我= 0，
		len = elems.length,
		批量=键==空；

	// 设置多个值
	如果（toType（键）===“对象”）{
		可链接=真；
		对于（我在关键）{
			access(elems, fn, i, key[i], true, emptyGet, raw);
		}

	//设置一个值
	} 否则如果（价值！==未定义）{
		可链接=真；

		如果（！isFunction（价值））{
			原始=真；
		}

		如果（批量）{

			// 对整个集合运行批量操作
			如果（原始）{
				fn.call(元素, 值);
				fn = 空；

			// ...执行函数值时除外
			} 别的 {
				散装 = fn；
				fn = 函数（元素，_键，值）{
					返回 bulk.call(jQuery(elem),value);
				};
			}
		}

		如果（fn）{
			对于（；我 < 长度；我++）{
				fn(
					elems[i], key, raw ?
						价值 ：
						value.call( elems[ i ], i, fn( elems [ i ], key ) )
				);
			}
		}
	}

	如果（可链接）{
		返回元素；
	}

	// 获取
	如果（批量）{
		返回 fn.call(elems);
	}

	返回长度？fn( elems[ 0 ], key ) : emptyGet;
};


// 匹配虚线字符串以进行骆驼化
var rmsPrefix = /^-ms-/,
	rdashAlpha = /-([az])/g;

// 被 camelCase 用作 replace() 的回调
函数 fcamelCase( _all, letter ) {
	返回 letter.toUpperCase();
}

// 将虚线转换为驼峰式；由 css 和数据模块使用
// 支持：IE <=9 - 11，Edge 12 - 15
// Microsoft 忘记设置供应商前缀 (trac-9572)
函数驼峰式（字符串）{
	返回 string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
}
var acceptData = 函数（所有者）{

	// 只接受：
	// - 节点
	// - 节点.ELEMENT_NODE
	// - 节点.DOCUMENT_NODE
	// - 目的
	// - 任何
	返回 owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
};




函数数据（）{
	this.expando = jQuery.expando + Data.uid++;
}

数据.uid = 1;

数据.原型={

	缓存：函数（所有者）{

		// 检查所有者对象是否已经有缓存
		var value = owner[ this.expando ];

		// 如果没有，创建一个
		如果（！值）{
			价值={}；

			// 我们可以接受现代浏览器中非元素节点的数据，
			// 但我们不应该，请参阅 trac-8335。
			// 总是返回一个空对象。
			如果（接受数据（所有者））{

				// 如果它是一个不太可能被字符串化或循环的节点
				// 使用普通赋值
				如果（所有者.nodeType）{
					所有者[ this.expando ] = 值；

				// 否则将其保护在不可枚举的属性中
				// configurable 必须为 true 才能允许属性
				// 删除数据时删除
				} 别的 {
					Object.defineProperty( 所有者, this.expando, {
						价值：价值，
						可配置：真
					});
				}
			}
		}

		返回值；
	},
	设置：函数（所有者、数据、值）{
		变种道具，
			cache = this.cache(所有者);

		// 句柄：[所有者，键，值] args
		// 始终使用驼峰式键 (gh-2257)
		如果（数据类型===“字符串”）{
			缓存[驼峰式（数据）] = 值；

		// 句柄：[所有者，{属性}] args
		} 别的 {

			// 将属性一个一个复制到缓存对象中
			对于（数据中的道具）{
				缓存[驼峰式(prop)] = data[prop];
			}
		}
		返回缓存；
	},
	得到：函数（所有者，密钥）{
		返回键 === 未定义？
			这个缓存（所有者）：

			// 始终使用驼峰式键 (gh-2257)
			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
	},
	访问：功能（所有者，键，值）{

		// 在以下任一情况下：
		//
		// 1. 没有指定键
		// 2. 指定了字符串键，但未提供值
		//
		// 取“读”路径，让get方法判断
		// 分别返回哪个值：
		//
		// 1. 整个缓存对象
		// 2. key 存放的数据
		//
		如果（键===未定义||
				( ( key && typeof key === "string" ) && value === undefined ) ) {

			返回 this.get(所有者, 密钥);
		}

		// 当键不是字符串时，或者既是键又是值
		// 指定、设置或扩展（现有对象）：
		//
		// 1. 属性对象
		// 2. 键和值
		//
		this.set（所有者，键，值）；

		// 因为“set”路径可以有两个可能的入口点
		// 根据采用的路径返回预期数据[*]
		返回值 !== 未定义？值：键；
	},
	删除：函数（所有者，密钥）{
		变量我，
			缓存=所有者[this.expando]；

		如果（缓存===未定义）{
			返回;
		}

		如果（关键！==未定义）{

			// 支持数组或空格分隔的键字符串
			如果（Array.isArray（键））{

				// 如果 key 是一个键数组...
				// 我们总是设置驼峰式键，所以删除它。
				key = key.map(驼峰式);
			} 别的 {
				key = camelCase( key );

				// 如果存在带空格的键，则使用它。
				// 否则，通过匹配非空白创建一个数组
				键 = 缓存中的键？
					[ 钥匙 ] ：
					( key.match( rnothtmlwhite ) || [] );
			}

			i = key.length;

			当我 -  ） {
				删除缓存[key[i]]；
			}
		}

		// 如果没有更多数据，则移除 expando
		如果（键===未定义|| jQuery.isEmptyObject（缓存））{

			// 支持：Chrome <=35 - 45
			// Webkit 和 Blink 性能在删除属性时受到影响
			// 来自 DOM 节点，所以改为设置为 undefined
			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607（错误限制）
			如果（所有者.nodeType）{
				所有者[ this.expando ] = undefined;
			} 别的 {
				删除所有者[this.expando]；
			}
		}
	},
	hasData：函数（所有者）{
		var cache = owner[this.expando];
		返回缓存 !== undefined && !jQuery.isEmptyObject( 缓存 );
	}
};
var dataPriv = new Data();

变种数据用户=新数据（）；



// 实现总结
//
// 1. 强制 API 表面和语义与 1.9.x 分支兼容
// 2. 通过减少存储提高模块的可维护性
// 单一机制的路径。
// 3. 使用相同的单一机制来支持“私有”和“用户”数据。
// 4. _Never_ 将“私有”数据暴露给用户代码（TODO：Drop _data、_removeData）
// 5. 避免暴露用户对象的实现细节（例如 expando 属性）
// 6. 为2014年WeakMap的实现升级提供了清晰的路径

var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
	rmultiDash = /[AZ]/g;

函数 getData( 数据 ) {
	如果（数据===“真”）{
		返回真；
	}

	如果（数据===“假”）{
		返回假；
	}

	如果（数据===“空”）{
		返回空值；
	}

	// 只有在不改变字符串的情况下才转换为数字
	如果（数据===+数据+“”）{
		返回+数据；
	}

	如果（rbrace.test（数据））{
		返回 JSON.parse(数据);
	}

	返回数据；
}

函数数据属性（元素，键，数据）{
	变量名称；

	// 如果内部没有发现任何东西，尝试获取任何
	// 来自 HTML5 data-* 属性的数据
	如果（数据 === 未定义 && elem.nodeType === 1）{
		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
		data = elem.getAttribute(名称);

		如果（数据类型===“字符串”）{
			尝试 {
				数据 = getData( 数据 );
			} 抓住 (e) {}

			// 确保我们设置了数据，以便以后不会更改
			dataUser.set（元素，键，数据）；
		} 别的 {
			数据=未定义；
		}
	}
	返回数据；
}

jQuery.扩展（{
	有数据：函数（元素）{
		返回 dataUser.hasData( elem ) || dataPriv.hasData(元素);
	},

	数据：函数（元素，名称，数据）{
		返回 dataUser.access(elem, name, data);
	},

	移除数据：函数（元素，名称）{
		dataUser.remove(elem,name);
	},

	// TODO：现在所有对 _data 和 _removeData 的调用都已被替换
	// 通过直接调用 dataPriv 方法，可以弃用这些方法。
	_data: 函数（元素、名称、数据）{
		返回 dataPriv.access(elem, name, data);
	},

	_removeData：函数（元素，名称）{
		dataPriv.remove(elem,name);
	}
});

jQuery.fn.extend({
	数据：函数（键，值）{
		var i, 名称, 数据,
			元素 = 这个 [ 0 ],
			属性 = elem && elem.attributes;

		// 获取所有值
		如果（关键===未定义）{
			如果（这个。长度）{
				data = dataUser.get(elem);

				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
					i = 属性.长度；
					当我 -  ） {

						// 支持：仅 IE 11
						// attrs 元素可以为空 (trac-14894)
						如果（属性[我]）{
							name = attrs[ i ].name;
							如果 ( name.indexOf( "数据-" ) === 0 ) {
								name = camelCase( name.slice( 5 ) );
								dataAttr(元素, 名称, 数据[名称]);
							}
						}
					}
					dataPriv.set(elem, "hasDataAttrs", true );
				}
			}

			返回数据；
		}

		// 设置多个值
		如果（类型键===“对象”）{
			返回 this.each( 函数() {
				dataUser.set( 这个, 键 );
			});
		}

		返回访问（这个，函数（值）{
			变量数据；

			// 调用的 jQuery 对象（元素匹配）不为空
			//（因此有一个元素出现在 this[0]）和
			// `value` 参数不是未定义的。一个空的 jQuery 对象
			// elem = this[ 0 ] 将导致 `undefined`，这将
			// 如果尝试读取数据缓存则抛出异常。
			如果（元素 && 值 === 未定义）{

				// 尝试从缓存中获取数据
				// key 在数据中总是驼峰式的
				data = dataUser.get( elem, key );
				如果（数据！==未定义）{
					返回数据；
				}

				// 尝试“发现”中的数据
				// HTML5 自定义数据-* 属性
				data = dataAttr(元素, 键);
				如果（数据！==未定义）{
					返回数据；
				}

				// 我们真的很努力，但是数据不存在。
				返回;
			}

			// 设置数据...
			this.each(函数(){

				// 我们总是存储驼峰式的键
				dataUser.set（这个，键，值）;
			});
		}, null, value, arguments.length > 1, null, true );
	},

	移除数据：函数（键）{
		返回 this.each( 函数() {
			dataUser.remove(这个，键);
		});
	}
});


jQuery.扩展（{
	队列：函数（元素，类型，数据）{
		变量队列；

		如果（元素）{
			类型=（类型||“fx”）+“队列”；
			queue = dataPriv.get(元素,类型);

			// 如果这只是一个查找，通过快速退出来加速出队
			如果（数据）{
				如果（！队列|| Array.isArray（数据））{
					queue = dataPriv.access(elem, type, jQuery.makeArray(data));
				} 别的 {
					queue.push(数据);
				}
			}
			返回队列 || [];
		}
	},

	出列：函数（elem，类型）{
		类型 = 类型 || “外汇”；

		var queue = jQuery.queue(elem, type),
			startLength = queue.length,
			fn = queue.shift(),
			hooks = jQuery._queueHooks(elem, type),
			接下来=功能（）{
				jQuery.dequeue(elem, 类型);
			};

		// 如果 fx 队列出队，总是移除进度哨兵
		如果（fn ===“进行中”）{
			fn = queue.shift();
			起始长度--;
		}

		如果（fn）{

			// 添加一个进度哨兵以防止 fx 队列被
			// 自动出队
			如果（类型===“fx”）{
				queue.unshift(“进行中”);
			}

			// 清空最后一个队列停止函数
			删除 hooks.stop；
			fn.call(elem, next, hooks);
		}

		如果（！startLength && 挂钩）{
			hooks.empty.fire();
		}
	},

	// 非公开 - 生成一个 queueHooks 对象，或返回当前对象
	_queueHooks：函数（元素，类型）{
		var key = type + "queueHooks";
		返回 dataPriv.get( elem, key ) || dataPriv.access(元素，密钥，{
			empty: jQuery.Callbacks( "once memory" ).add( function() {
				dataPriv.remove(elem, [type + "queue", key ] );
			})
		});
	}
});

jQuery.fn.extend({
	队列：函数（类型，数据）{
		变量设置器= 2；

		如果（类型类型！==“字符串”）{
			数据=类型；
			类型=“FX”；
			二传手--;
		}

		如果（参数.length < setter）{
			返回 jQuery.queue(this[0],类型);
		}

		返回数据 === 未定义？
			这 ：
			this.each(函数(){
				var queue = jQuery.queue(this, type, data);

				// 确保这个队列有一个钩子
				jQuery._queueHooks（这个，类型）；

				如果（类型===“fx”&&队列[0]！==“进行中”）{
					jQuery.dequeue（这个，类型）；
				}
			});
	},
	出列：函数（类型）{
		返回 this.each( 函数() {
			jQuery.dequeue（这个，类型）；
		});
	},
	清除队列：函数（类型）{
		return this.queue( 类型 || "fx", [] );
	},

	// 当某种类型的队列时得到一个解决的承诺
	// 被清空（默认为fx类型）
	承诺：功能（类型，对象）{
		变量 tmp，
			计数 = 1，
			defer = jQuery.Deferred(),
			元素=这个，
			我=这个。长度，
			解决=功能（）{
				如果（！（--计数））{
					defer.resolveWith( 元素, [ 元素 ] );
				}
			};

		如果（类型类型！==“字符串”）{
			对象 = 类型；
			类型 = 未定义；
		}
		类型 = 类型 || “外汇”；

		当我 -  ） {
			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
			如果（tmp && tmp.empty）{
				计数++；
				tmp.empty.add（解析）；
			}
		}
		解决（）;
		返回 defer.promise(obj);
	}
});
var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;

var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([az%]*)$", "i" );


var cssExpand = [ "顶部", "右", "底部", "左" ];

var documentElement = document.documentElement;



	var isAttached = 函数（元素）{
			返回 jQuery.contains(elem.ownerDocument, elem);
		},
		组成={组成：真}；

	// 支持：仅限 IE 9 - 11+、Edge 12 - 18+、iOS 10.0 - 10.2
	// 尽可能检查阴影 DOM 边界的附件 (gh-3504)
	// 支持：仅限 iOS 10.0-10.2
	// 早期的 iO​​S 10 版本支持 `attachShadow` 但不支持 `getRootNode`,
	// 导致错误。我们需要检查“getRootNode”。
	如果（文档元素.getRootNode）{
		isAttached = 函数（元素）{
			返回 jQuery.contains(elem.ownerDocument, elem) ||
				elem.getRootNode( composed ) === elem.ownerDocument;
		};
	}
var isHiddenWithinTree = function( elem, el ) {

		// isHiddenWithinTree 可能会被 jQuery#filter 函数调用；
		// 在这种情况下，元素将是第二个参数
		elem = el || 元素;

		// 内联风格胜过一切
		返回 elem.style.display === “无” ||
			elem.style.display === "" &&

			// 否则，检查计算样式
			// 支持：Firefox <=43 - 45
			// 断开连接的元素可以有computed display: none，所以先确认elem是
			// 在文档中。
			已附加（元素）&&

			jQuery.css(elem, "显示") === "无";
	};



function adjustCSS( elem, prop, valueParts, tween ) {
	var 调整，规模，
		最大迭代次数 = 20，
		当前值 = 补间？
			功能（） {
				返回 tween.cur();
			} :
			功能（） {
				返回 jQuery.css（元素，道具，“”）;
			},
		初始=当前值（），
		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),

		// 潜在的单位不匹配需要计算起始值
		initialInUnit = elem.nodeType &&
			( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
			rcssNum.exec( jQuery.css( elem, prop ) );

	如果（initialInUnit && initialInUnit[3]！==单位）{

		// 支持：Firefox <=54
		// 将迭代目标值减半以防止 CSS 上限的干扰 (gh-2144)
		初始 = 初始 / 2;

		// jQuery.css 报告的信任单元
		单位=单位|| initialInUnit[ 3 ];

		// 从非零起点迭代逼近
		initialInUnit = +初始|| 1;

		while ( maxIterations-- ) {

			// 评估并更新我们的最佳猜测（将归零的猜测加倍）。
			// 如果比例等于或超过 1（使旧*新产品非正），则完成。
			jQuery.style( elem, prop, initialInUnit + unit );
			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
				最大迭代次数 = 0；
			}
			initialInUnit = initialInUnit / 规模;

		}

		初始单位 = 初始单位 * 2;
		jQuery.style( elem, prop, initialInUnit + unit );

		// 确保我们稍后更新补间属性
		价值部分 = 价值部分 || [];
	}

	如果（价值部分）{
		initialInUnit = +initialInUnit || +初始|| 0;

		// 如果指定，应用相对偏移量 (+=/-=)
		调整 = valueParts [ 1 ] ?
			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] ：
			+价值部分[2]；
		如果（吐温）{
			tween.unit = 单位；
			tween.start = initialInUnit;
			tween.end = 已调整；
		}
	}
	回报调整；
}


var defaultDisplayMap = {};

函数 getDefaultDisplay(elem){
	可变温度，
		doc = elem.ownerDocument,
		nodeName = elem.nodeName,
		display = defaultDisplayMap[ 节点名称 ];

	如果（显示）{
		返回显示；
	}

	temp = doc.body.appendChild( doc.createElement( nodeName ) );
	display = jQuery.css(temp, "display" );

	temp.parentNode.removeChild( temp );

	如果（显示===“无”）{
		显示=“块”；
	}
	defaultDisplayMap[ nodeName ] = 显示；

	返回显示；
}

功能显示隐藏（元素，显示）{
	可变显示，元素，
		值 = [],
		指数 = 0,
		长度=元素.长度；

	// 为需要改变的元素确定新的显示值
	for (; index < length; index++) {
		elem = 元素[索引];
		如果（！elem.style）{
			继续;
		}

		显示 = elem.style.display;
		如果（显示）{

			// 由于我们强制级联隐藏元素可见，因此立即（且缓慢）
			// 在第一个循环中需要检查，除非我们有一个非空的显示值（要么
			// 内联或即将恢复）
			如果（显示===“无”）{
				values[ index ] = dataPriv.get( elem, "display" ) || 无效的;
				如果（！值[索引]）{
					elem.style.display = "";
				}
			}
			如果 (elem.style.display === "" && isHiddenWithinTree( elem ) ) {
				值[ 索引 ] = getDefaultDisplay( elem );
			}
		} 别的 {
			如果（显示！==“无”）{
				值[索引] =“无”；

				// 记住我们要覆盖的内容
				dataPriv.set(elem, "显示", 显示);
			}
		}
	}

	// 设置二次循环中元素的显示，避免不断回流
	对于（索引= 0；索引<长度；索引++）{
		如果（值[索引]！=空）{
			元素[索引].style.display =值[索引];
		}
	}

	返回元素；
}

jQuery.fn.extend({
	显示：函数（）{
		返回显示隐藏（这个，真）；
	},
	隐藏：函数（）{
		返回显示隐藏（这个）；
	},
	切换：功能（状态）{
		如果（类型状态===“布尔值”）{
			返回状态？this.show() : this.hide();
		}

		返回 this.each( 函数() {
			如果（isHiddenWithinTree（这个））{
				jQuery( 这个 ).show();
			} 别的 {
				jQuery( 这个 ).隐藏();
			}
		});
	}
});
var rcheckableType = ( /^(?:checkbox|radio)$/i );

var rtagName = ( /<([az][^\/\0>\x20\t\r\n\f]*)/i );

var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );



（ 功能（） {
	var fragment = document.createDocumentFragment(),
		div = fragment.appendChild( document.createElement( "div" ) ),
		input = document.createElement("输入");

	// 支持：仅限 Android 4.0 - 4.3
	// 如果设置了名称，则检查状态是否丢失 (trac-11217)
	// 支持：Windows Web 应用程序 (WWA)
	// `name` 和 `type` 必须为 WWA 使用 .setAttribute (trac-14901)
	input.setAttribute( "type", "radio" );
	input.setAttribute("选中", "选中");
	input.setAttribute( "名称", "t" );

	div.appendChild(输入);

	// 支持：仅限 Android <=4.1
	// 较旧的 WebKit 无法在片段中正确克隆已检查的状态
	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;

	// 支持：仅限 IE <=11
	// 确保文本区域（和复选框）的默认值被正确克隆
	div.innerHTML = "<textarea>x</textarea>";
	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;

	// 支持：仅限 IE <=9
	// IE <=9 在插入到外部时用它们的内容替换 <option> 标签
	// 选择元素。
	div.innerHTML = "<选项></选项>";
	support.option = !!div.lastChild;
} )();


// 我们必须关闭这些标签以支持 XHTML (trac-13200)
var wrapMap = {

	// XHTML 解析器不会神奇地将元素插入到
	// 与标签汤解析器相同的方式。所以我们不能缩短
	// 通过省略 <tbody> 或其他必需的元素来做到这一点。
	thead: [ 1, "<table>", "</table>" ],
	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],

	_default: [ 0, "", "" ]
};

wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;

// 支持：仅限 IE <=9
如果（！support.option）{
	wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
}


函数 getAll（上下文，标签）{

	// 支持：仅限 IE <=9 - 11
	// 使用 typeof 避免在宿主对象上调用零参数方法 (trac-15151)
	变种;

	if ( typeof context.getElementsByTagName !== "undefined" ) {
		ret = context.getElementsByTagName(标签||“*”);

	} else if ( typeof context.querySelectorAll !== "undefined" ) {
		ret = context.querySelectorAll(标签||“*”);

	} 别的 {
		ret = [];
	}

	if ( tag === undefined || tag && nodeName( context, tag ) ) {
		返回 jQuery.merge([上下文],ret);
	}

	返还；
}


// 将脚本标记为已经被评估
函数 setGlobalEval(elems, refElements){
	变种我= 0，
		l = 元素.长度；

	对于（；我<我；我++）{
		dataPriv.set(
			元素[我],
			“全球评估”，
			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
		);
	}
}


var rhtml = /<|&#?\w+;/;

函数 buildFragment（元素、上下文、脚本、选择、忽略）{
	var elem, tmp, tag, wrap, attached, j,
		fragment = context.createDocumentFragment(),
		节点 = [],
		我 = 0,
		l = 元素.长度；

	对于（；我<我；我++）{
		elem = elems[我];

		如果（元素 || 元素 === 0）{

			// 直接添加节点
			如果（toType（elem）===“对象”）{

				// 支持：仅限 Android <=4.0，仅限 PhantomJS 1
				// push.apply(_, arraylike) 在古老的 WebKit 上抛出
				jQuery.merge(节点, elem.nodeType ? [ elem ] : elem );

			// 将非html转换为文本节点
			} else if ( !rhtml.test( elem ) ) {
				nodes.push(context.createTextNode(elem));

			// 将 html 转换为 DOM 节点
			} 别的 {
				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );

				// 反序列化标准表示
				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
				wrap = wrapMap[标签] || wrapMap._default;
				tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2];

				// 通过包装器下降到正确的内容
				j = wrap[0];
				而（j--）{
					tmp = tmp.lastChild;
				}

				// 支持：仅限 Android <=4.0，仅限 PhantomJS 1
				// push.apply(_, arraylike) 在古老的 WebKit 上抛出
				jQuery.merge(节点, tmp.childNodes);

				// 记住顶层容器
				tmp = fragment.firstChild;

				// 确保创建的节点是孤立的 (trac-12392)
				tmp.textContent = "";
			}
		}
	}

	// 从片段中移除包装器
	fragment.textContent = "";

	我 = 0;
	while ( ( elem = nodes[ i++ ] ) ) {

		// 跳过上下文集合中已有的元素 (trac-4087)
		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
			如果（忽略）{
				ignored.push(elem);
			}
			继续;
		}

		附加 = isAttached(元素);

		//附加到片段
		tmp = getAll( fragment.appendChild( elem ), "script" );

		// 保存脚本评估历史
		如果（附上）{
			setGlobalEval( tmp );
		}

		// 捕获可执行文件
		如果（脚本）{
			j = 0;
			while ( ( elem = tmp[ j++ ] ) ) {
				如果 ( rscriptType.test( elem.type || "" ) ) {
					scripts.push(元素);
				}
			}
		}
	}

	返回片段；
}


var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;

函数 returnTrue() {
	返回真；
}

函数 returnFalse() {
	返回假；
}

function on( elem, types, selector, data, fn, one ) {
	var origFn，类型；

	// 类型可以是类型/处理程序的映射
	如果（typeof类型===“对象”）{

		// ( types-Object, selector, data )
		如果（类型选择器！==“字符串”）{

			//（类型-对象，数据）
			数据=数据|| 选择器；
			选择器=未定义；
		}
		对于（输入类型）{
			on( elem, type, selector, data, types[ type ], one );
		}
		返回元素；
	}

	如果（数据== null && fn == null）{

		//（类型，fn）
		fn = 选择器；
		数据=选择器=未定义；
	} 否则如果（fn == null）{
		如果（类型选择器===“字符串”）{

			//（类型，选择器，fn）
			fn = 数据；
			数据=未定义；
		} 别的 {

			//（类型，数据，fn）
			fn = 数据；
			数据=选择器；
			选择器=未定义；
		}
	}
	如果（fn ===假）{
		fn = 返回假；
	}否则如果（！fn）{
		返回元素；
	}

	如果（一===1）{
		origFn = fn;
		fn = 函数（事件）{

			// 可以使用空集，因为事件包含信息
			jQuery().off(事件);
			返回 origFn.apply(this, arguments);
		};

		// 使用相同的 guid 以便调用者可以使用 origFn 删除
		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
	}
	返回 elem.each( 函数 () {
		jQuery.event.add(this, types, fn, data, selector);
	});
}

/*
 * 用于管理事件的辅助函数——不是公共接口的一部分。
 * 支持 Dean Edwards 的 addEvent 库的许多想法。
 */
jQuery.event = {

	全球的： {}，

	添加：函数（元素，类型，处理程序，数据，选择器）{

		var handleObjIn, eventHandle, tmp,
			事件，t，handleObj，
			特殊的，处理程序，类型，命名空间，origType，
			elemData = dataPriv.get(elem);

		// 仅将事件附加到接受数据的对象
		如果（！acceptData（元素））{
			返回;
		}

		// 调用者可以传入自定义数据的对象来代替处理程序
		如果（处理程序。处理程序）{
			handleObjIn = 处理程序；
			handler = handleObjIn.handler;
			选择器 = handleObjIn.selector;
		}

		// 确保无效的选择器在附加时抛出异常
		// 如果 elem 是非元素节点（例如，文档），则对 documentElement 进行评估
		如果（选择器）{
			jQuery.find.matchesSelector(documentElement, 选择器);
		}

		// 确保处理程序具有唯一 ID，用于稍后查找/删除它
		如果（！handler.guid）{
			handler.guid = jQuery.guid++;
		}

		// 初始化元素的事件结构和主处理程序，如果这是第一个
		如果（！（事件= elemData.events））{
			events = elemData.events = Object.create( null );
		}
		如果 ( !( eventHandle = elemData.handle ) ) {
			eventHandle = elemData.handle = function( e ) {

				// 丢弃 jQuery.event.trigger() 的第二个事件和
				// 在页面卸载后调用事件
				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
					jQuery.event.dispatch.apply（元素，参数）：未定义；
			};
		}

		// 处理以空格分隔的多个事件
		types = ( 类型 || "" ).match( rnothtmlwhite ) || [ "" ];
		t = 类型.长度；
		同时 ( t-- ) {
			tmp = rtypenamespace.exec(类型[t])|| [];
			type = origType = tmp[ 1 ];
			命名空间 = ( tmp[ 2 ] || "" ).split( "." ).sort();

			// *必须* 是一种类型，没有附加仅命名空间的处理程序
			如果（！类型）{
				继续;
			}

			// 如果事件改变了它的类型，为改变的类型使用特殊的事件处理程序
			special = jQuery.event.special[类型] || {};

			// 如果选择器已定义，则确定特殊事件 api 类型，否则为给定类型
			类型=（选择器？special.delegateType：special.bindType）|| 类型;

			// 根据新重置的类型更新 special
			special = jQuery.event.special[类型] || {};

			// handleObj 被传递给所有的事件处理器
			handleObj = jQuery.extend({
				类型：类型，
				原始类型：原始类型，
				数据：数据，
				处理程序：处理程序，
				guid：handler.guid，
				选择器：选择器，
				needsContext: 选择器 && jQuery.expr.match.needsContext.test( 选择器 ),
				命名空间：namespaces.join(".")
			}, handleObjIn );

			// 如果我们是第一个，则初始化事件处理程序队列
			如果（！（处理程序=事件[类型]））{
				handlers = events[ 类型 ] = [];
				handlers.delegateCount = 0;

				// 只有在特殊事件处理程序返回 false 时才使用 addEventListener
				如果 (!special.setup ||
					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {

					如果（elem.addEventListener）{
						elem.addEventListener( 类型, eventHandle );
					}
				}
			}

			如果（特殊。添加）{
				special.add.call(elem, handleObj);

				如果（！handleObj.handler.guid）{
					handleObj.handler.guid = handler.guid;
				}
			}

			// 添加到元素的处理程序列表中，委托在前面
			如果（选择器）{
				handlers.splice(handlers.delegateCount++, 0, handleObj);
			} 别的 {
				handlers.push(handleObj);
			}

			// 跟踪曾经使用过哪些事件，以进行事件优化
			jQuery.event.global[ 类型 ] = true;
		}

	},

	// 从元素中分离一个事件或一组事件
	移除：函数（元素、类型、处理程序、选择器、映射类型）{

		var j, origCount, tmp,
			事件，t，handleObj，
			特殊的，处理程序，类型，命名空间，origType，
			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );

		如果（！elemData ||！（事件= elemData.events））{
			返回;
		}

		// types 中的每个 type.namespace 一次；类型可以省略
		types = ( 类型 || "" ).match( rnothtmlwhite ) || [ "" ];
		t = 类型.长度；
		同时 ( t-- ) {
			tmp = rtypenamespace.exec(类型[t])|| [];
			type = origType = tmp[ 1 ];
			命名空间 = ( tmp[ 2 ] || "" ).split( "." ).sort();

			// 取消绑定元素的所有事件（在这个命名空间上，如果提供的话）
			如果（！类型）{
				for（输入事件）{
					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
				}
				继续;
			}

			special = jQuery.event.special[类型] || {};
			类型=（选择器？special.delegateType：special.bindType）|| 类型;
			处理程序=事件[类型] || [];
			tmp = tmp[2] &&
				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );

			// 删除匹配事件
			origCount = j = handlers.length;
			而（j--）{
				handleObj = handlers[j];

				如果 ( ( mappedTypes || origType === handleObj.origType ) &&
					( !handler || handler.guid === handleObj.guid ) &&
					( !tmp || tmp.test( handleObj.namespace ) ) &&
					( !selector || 选择器 === handleObj.selector ||
						选择器 === "**" && handleObj.selector ) ) {
					handlers.splice(j, 1);

					如果（handleObj.selector）{
						handlers.delegateCount--;
					}
					如果（特殊。删除）{
						special.remove.call(elem, handleObj);
					}
				}
			}

			// 如果我们删除了一些东西并且不存在更多的处理程序，则删除通用事件处理程序
			//（避免在删除特殊事件处理程序期间无限递归的可能性）
			如果 ( origCount && !handlers.length ) {
				如果 (!special.teardown ||
					special.teardown.call( elem, 命名空间, elemData.handle ) === false ) {

					jQuery.removeEvent(元素, 类型, elemData.handle);
				}

				删除事件[类型]；
			}
		}

		// 如果不再使用，则删除数据和 expando
		如果（jQuery.isEmptyObject（事件））{
			dataPriv.remove( elem, "处理事件" );
		}
	},

	调度：函数（nativeEvent）{

		var i, j, ret, matched, handleObj, handlerQueue,
			args = new Array(arguments.length),

			// 从原生事件对象创建一个可写的 jQuery.Event
			event = jQuery.event.fix( nativeEvent ),

			处理程序 = (
				dataPriv.get（这个，“事件”）|| 对象.create( null )
			)[ 事件类型 ] || [],
			special = jQuery.event.special[ event.type ] || {};

		// 使用固定的 jQuery.Event 而不是（只读的）本地事件
		args[ 0 ] = 事件；

		for ( i = 1; i < arguments.length; i++ ) {
			args[i] = arguments[i];
		}

		event.delegateTarget = 这个；

		// 为映射类型调用 preDispatch 钩子，如果需要，让它退出
		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
			返回;
		}

		// 确定处理程序
		handlerQueue = jQuery.event.handlers.call(this, event, handlers);

		// 首先运行委托；他们可能想阻止我们下方的传播
		我 = 0;
		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
			event.currentTarget = matched.elem;

			j = 0;
			while ( ( handleObj = matched.handlers[ j++ ] ) &&
				!event.isImmediatePropagationStopped() ) {

				// 如果事件是命名空间的，那么每个处理程序只有在它是
				// 特别通用或其命名空间是事件的超集。
				如果 (!event.rnamespace || handleObj.namespace === false ||
					event.rnamespace.test( handleObj.namespace ) ) {

					event.handleObj = handleObj;
					event.data = handleObj.data;

					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
						handleObj.handler).apply(matched.elem, args);

					如果（返回！==未定义）{
						如果 ( ( event.result = ret ) === false ) {
							事件.preventDefault();
							事件.stopPropagation();
						}
					}
				}
			}
		}

		// 为映射类型调用 postDispatch 钩子
		如果 ( special.postDispatch ) {
			special.postDispatch.call(this, event);
		}

		返回事件.result；
	},

	处理程序：函数（事件，处理程序）{
		var i, handleObj, sel, matchedHandlers, matchedSelectors,
			处理队列 = [],
			delegateCount = handlers.delegateCount,
			cur = event.target;

		// 查找委托处理程序
		如果（委托计数&&

			// 支持：IE <=9
			// 黑洞 SVG <use> 实例树 (trac-13180)
			当前节点类型 &&

			// 支持：Firefox <=42
			// 抑制指示非主指针按钮的违反规范的点击 (trac-3861)
			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
			// 支持：仅 IE 11
			// ...但不是无线电输入的箭头键“点击”，它可以有 `button` -1 (gh-2343)
			!( event.type === "click" && event.button >= 1 ) ) {

			对于 ( ; cur !== this; cur = cur.parentNode || this ) {

				// 不要检查非元素 (trac-13208)
				// 不要处理对禁用元素的点击（trac-6911、trac-8165、trac-11382、trac-11764）
				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
					matchedHandlers = [];
					matchedSelectors = {};
					for ( i = 0; i < delegateCount; i++ ) {
						handleObj = handlers[我];

						// 不要与 Object.prototype 属性冲突 (trac-13203)
						sel = handleObj.selector + " ";

						如果（匹配选择器[选择器] ===未定义）{
							matchedSelectors[ sel ] = handleObj.needsContext ？
								jQuery( sel, this ).index( cur ) > -1 :
								jQuery.find( sel, this, null, [ cur ] ).length;
						}
						如果（匹配选择器[选择器]）{
							matchedHandlers.push(handleObj);
						}
					}
					如果 ( matchedHandlers.length ) {
						handlerQueue.push({ elem: cur, handlers: matchedHandlers } );
					}
				}
			}
		}

		// 添加剩余的（直接绑定的）处理程序
		当前=这个；
		如果 ( 委托计数 < handlers.length ) {
			handlerQueue.push({ elem: cur, handlers: handlers.slice( delegateCount ) } );
		}

		返回处理队列；
	},

	addProp：函数（名称，钩子）{
		Object.defineProperty(jQuery.Event.prototype, 名称, {
			可枚举：真实，
			可配置：真，

			得到：isFunction（挂钩）？
				功能（） {
					如果（this.originalEvent）{
						返回钩子（this.originalEvent）；
					}
				} :
				功能（） {
					如果（this.originalEvent）{
						返回 this.originalEvent[名称]；
					}
				},

			设置：函数（值）{
				Object.defineProperty(这个，名字，{
					可枚举：真实，
					可配置：真，
					可写：真，
					价值：价值
				});
			}
		});
	},

	修复：函数（原始事件）{
		返回 originalEvent[jQuery.expando]？
			原始事件：
			新的 jQuery.Event( originalEvent );
	},

	特别的： {
		加载： {

			// 防止触发的image.load事件冒泡到window.load
			无气泡：真
		},
		点击： {

			// 利用本机事件来确保可检查输入的正确状态
			设置：函数（数据）{

				// 对于 _default 的相互压缩性，将 `this` 访问替换为本地变量。
				//`|| data` 是死代码，仅用于通过缩小保留变量。
				var el = 这个 || 数据;

				// 声明第一个处理程序
				如果（rcheckableType.test（el.type）&&
					el.click && nodeName( el, "输入" ) ) {

					// dataPriv.set(el, "click", ... )
					leverageNative( el, "点击", true );
				}

				// 返回 false 允许调用者正常处理
				返回假；
			},
			触发器：函数（数据）{

				// 对于 _default 的相互压缩性，将 `this` 访问替换为本地变量。
				//`|| data` 是死代码，仅用于通过缩小保留变量。
				var el = 这个 || 数据;

				// 在触发点击之前强制设置
				如果（rcheckableType.test（el.type）&&
					el.click && nodeName( el, "输入" ) ) {

					leverageNative( el, "点击" );
				}

				// 返回非假以允许正常的事件路径传播
				返回真；
			},

			// 为了跨浏览器的一致性，抑制链接上的原生 .click()
			// 如果我们当前在一个杠杆化的原生事件栈中，也要阻止它
			_default：函数（事件）{
				var target = event.target;
				返回 rcheckableType.test( target.type ) &&
					target.click && nodeName( target, "input" ) &&
					dataPriv.get（目标，“点击”）||
					节点名（目标，“一”）；
			}
		},

		卸载前：{
			postDispatch：函数（事件）{

				// 支持：Firefox 20+
				// 如果未设置 returnValue 字段，Firefox 不会发出警报。
				如果（事件。结果！==未定义&&事件。原始事件）{
					event.originalEvent.returnValue = event.result;
				}
			}
		}
	}
};

// 确保存在处理手动触发的事件侦听器
// 通过中断进度直到重新调用以响应合成事件
// *native* 直接触发的事件，确保状态改变
// 在调用其他侦听器之前已经发生。
函数 leverageNative(el,type,isSetup){

	// 缺少 `isSetup` 表示触发调用，必须通过 jQuery.event.add 强制设置
	如果（！isSetup）{
		如果（dataPriv.get（el，类型）===未定义）{
			jQuery.event.add( el, type, returnTrue );
		}
		返回;
	}

	// 将控制器注册为所有事件命名空间的特殊通用处理程序
	dataPriv.set( el, type, false );
	jQuery.event.add( el, 类型, {
		命名空间：假的，
		处理程序：函数（事件）{
			可变结果，
				saved = dataPriv.get(this, type);

			如果 ( ( event.isTrigger & 1 ) && this[ 类型 ] ) {

				// 中断外部合成 .trigger()ed 事件的处理
				如果（！保存）{

					// 存储处理内部本机事件时使用的参数
					// 总会有至少一个参数（一个事件对象），所以这个数组
					// 不会与剩余的捕获对象混淆。
					saved = slice.call(参数);
					dataPriv.set（这个，类型，保存）;

					// 触发本机事件并捕获其结果
					这个类型 ]（）;
					结果 = dataPriv.get( 这个, 类型 );
					dataPriv.set(this,type,false);

					如果（保存！==结果）{

						// 取消外层合成事件
						event.stopImmediatePropagation();
						事件.preventDefault();

						返回结果；
					}

				// 如果这是一个带有冒泡代理的事件的内部合成事件
				//（焦点或模糊），假设代理项已经从触发传播
				// 本机事件并防止它再次发生在这里。
				// 这在技术上得到了 `.trigger()` 的顺序错误（其中
				// 冒泡代理传播*在*非冒泡基数之后），但这似乎
				// 没有重复那么糟糕。
				} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
					事件.stopPropagation();
				}

			// 如果这是上面触发的本地事件，那么现在一切正常
			// 使用原始参数触发内部合成事件
			} 否则如果（保存）{

				// ...并捕获结果
				dataPriv.set( 这个，类型，jQuery.event.trigger(
					已保存[ 0 ],
					saved.slice( 1 ),
					这
				));

				// 中止所有 jQuery 处理程序对本机事件的处理，同时允许
				// 要运行的同一元素上的本机处理程序。在目标上，这是实现的
				// 通过仅在 jQuery 事件上停止立即传播。然而，
				// 本机事件在每个级别上由 jQuery 重新包装
				// 传播所以为 jQuery 停止它的唯一方法是为
				// 每个人都通过原生的 `stopPropagation()`。这不是问题
				// focus/blur 不会冒泡，但它也会停止点击复选框
				// 和收音机。我们接受这个限制。
				事件.stopPropagation();
				event.isImmediatePropagationStopped = returnTrue;
			}
		}
	});
}

jQuery.removeEvent = 函数（元素，类型，句柄）{

	// 普通对象需要这个“if”
	如果 (elem.removeEventListener) {
		elem.removeEventListener（类型，句柄）；
	}
};

jQuery.Event = function(src, props){

	// 允许在没有 'new' 关键字的情况下实例化
	如果（！（这个 jQuery.Event 实例））{
		返回新的 jQuery.Event(src, props);
	}

	// 事件对象
	如果（源代码 && 源代码类型）{
		this.originalEvent = src;
		this.type = src.type;

		// 冒泡文档的事件可能已被标记为已阻止
		// 由树下的处理程序；反映正确的价值。
		this.isDefaultPrevented = src.defaultPrevented ||
				src.defaultPrevented === 未定义 &&

				// 支持：仅限 Android <=2.3
				src.returnValue === false ？
			返回真：
			返回假；

		// 创建目标属性
		// 支持：仅限 Safari <=6 - 7
		// 目标不应是文本节点（trac-504、trac-13143）
		this.target = ( src.target && src.target.nodeType === 3 ) ?
			来源.target.parentNode ：
			源代码目标；

		this.currentTarget = src.currentTarget;
		this.relatedTarget = src.relatedTarget;

	// 事件类型
	} 别的 {
		this.type = src;
	}

	// 将显式提供的属性放到事件对象上
	如果（道具）{
		jQuery.extend( 这个, 道具 );
	}

	// 如果传入事件没有时间戳，则创建时间戳
	this.timeStamp = src && src.timeStamp || 日期.现在();

	// 标记为固定
	这个[ jQuery.expando ] = true;
};

// jQuery.Event 基于 ECMAScript 语言绑定指定的 DOM3 事件
// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
jQuery.Event.prototype = {
	构造函数：jQuery.Event，
	isDefaultPrevented：返回假，
	isPropagationStopped: returnFalse,
	isImmediatePropagationStopped: returnFalse,
	isSimulated：假，

	防止默认：功能（）{
		var e = this.originalEvent;

		this.isDefaultPrevented = returnTrue;

		如果（e && ！this.isSimulated）{
			e.preventDefault();
		}
	},
	停止传播：函数（）{
		var e = this.originalEvent;

		this.isPropagationStopped = returnTrue;

		如果（e && ！this.isSimulated）{
			e.stopPropagation();
		}
	},
	stopImmediatePropagation：函数（）{
		var e = this.originalEvent;

		this.isImmediatePropagationStopped = returnTrue;

		如果（e && ！this.isSimulated）{
			e.stopImmediatePropagation();
		}

		this.stopPropagation();
	}
};

// 包括所有常见的事件道具，包括 KeyEvent 和 MouseEvent 特定道具
jQuery.each({
	altKey：是的，
	泡泡：真的，
	可取消：真，
	changedTouches：真实，
	Ctrl键：真，
	细节：真实，
	事件阶段：真，
	元键：是的，
	pageX: 是的，
	第 Y 页：正确，
	换档键：真，
	观点：真实，
	“字符”：是的，
	代码：真实，
	字符代码：真，
	关键：是的，
	键码：真，
	按钮：是的，
	按钮：真，
	客户X：是的，
	客户Y：是的，
	offsetX：真，
	偏移量Y：真，
	pointerId: 是的，
	指针类型：真，
	screenX：是的，
	屏幕Y：真实，
	targetTouches：真，
	toElement：真，
	触摸：真实的，
	其中：真实
}, jQuery.event.addProp );

jQuery.each({ focus: "focusin", blur: "focusout" }, function( type, delegateType ) {

	函数 focusMappedHandler(nativeEvent){
		如果（文档。文档模式）{

			// 支持：IE 11+
			// 当有人需要时，在文档上附加一个 focusin/focusout 处理程序
			// 聚焦/模糊。这是因为前者在IE中是同步的，而后者
			// 是异步的。在其他浏览器中，所有这些处理程序都是同步调用的。

			// 来自私有数据的 `handle` 已经包装了事件，但我们需要
			// 在这里更改 `type`。
			var handle = dataPriv.get(this, "handle"),
				event = jQuery.event.fix( nativeEvent );
			event.type = nativeEvent.type === “焦点”？“焦点”：“模糊”；
			event.isSimulated = true;

			// 首先，处理 focusin/focusout
			句柄（本机事件）；

			// ...然后，处理焦点/模糊
			//
			// focusin/focusout 时 focus/blur 不冒泡；仅通过模拟前者
			// 在较低级别调用处理程序。
			如果 ( 事件.target === event.currentTarget ) {

				// 设置部分调用 `leverageNative`，后者又调用
				// `jQuery.event.add`，所以事件句柄已经设置好了
				// 至此。
				句柄（事件）；
			}
		} 别的 {

			// 对于非 IE 浏览器，在文档上附加一个捕获处理程序
			// 当有人想要 focusin/focusout 时。
			jQuery.event.simulate( delegateType, nativeEvent.target,
				jQuery.event.fix( nativeEvent ) );
		}
	}

	jQuery.event.special[ 类型 ] = {

		// 如果可能，使用原生事件，这样模糊/焦点序列是正确的
		设置：功能（）{

			var 附加；

			// 声明第一个处理程序
			// dataPriv.set(this, "focus", ... )
			// dataPriv.set(this, "blur", ... )
			leverageNative（这个，类型，真）；

			如果（文档。文档模式）{

				// 支持：IE 9 - 11+
				// 我们对 focusin 和 focus（以及 focusout 和 blur）使用相同的本地处理程序
				// 所以我们需要协调这些事件之间的设置和拆卸部分。
				// 使用 `delegateType` 作为键，因为 `leverageNative` 已经使用了 `type`。
				attaches = dataPriv.get(this, delegateType);
				如果（！附件）{
					this.addEventListener( delegateType, focusMappedHandler );
				}
				dataPriv.set( this, delegateType, ( 附加 || 0 ) + 1 );
			} 别的 {

				// 返回 false 允许调用者正常处理
				返回假；
			}
		},
		触发器：函数（）{

			// 触发前强制设置
			leverageNative( 这个, 类型 );

			// 返回非假以允许正常的事件路径传播
			返回真；
		},

		拆解：函数（）{
			var 附加；

			如果（文档。文档模式）{
				attaches = dataPriv.get(this, delegateType) - 1;
				如果（！附件）{
					this.removeEventListener( delegateType, focusMappedHandler );
					dataPriv.remove(this, delegateType);
				} 别的 {
					dataPriv.set(this, delegateType, attaches);
				}
			} 别的 {

				// 返回 false 表示应该应用标准拆解
				返回假；
			}
		},

		// 如果我们当前在里面，则抑制本机焦点或模糊
		// 一个杠杆化的原生事件堆栈
		_default：函数（事件）{
			返回 dataPriv.get( event.target, type );
		},

		委托类型：委托类型
	};

	// 支持：Firefox <=44
	// Firefox 没有 focus(in | out) 事件
	// 相关票证 - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
	//
	// 支持：Chrome <=48 - 49，Safari <=9.0 - 9.1
	// focus(in | out) 事件在 focus & blur 事件之后触发，
	// 这是规范违规 - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
	// 相关票证 - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
	//
	// 支持：IE 9 - 11+
	// 为了保留 3.x 分支上保证的相对 focusin/focus & focusout/blur 事件顺序，
	// 为 IE 中的两个事件附加一个处理程序。
	jQuery.event.special[ delegateType ] = {
		设置：功能（）{

			// 处理：常规节点（通过 `this.ownerDocument`）、窗口
			//（通过 `this.document`）和文档（通过 `this`）。
			var doc = this.ownerDocument || 这个.document || 这，
				dataHolder = document.documentMode ? 这个：医生，
				attaches = dataPriv.get(dataHolder, delegateType);

			// 支持：IE 9 - 11+
			// 我们对 focusin 和 focus（以及 focusout 和 blur）使用相同的本地处理程序
			// 所以我们需要协调这些事件之间的设置和拆卸部分。
			// 使用 `delegateType` 作为键，因为 `leverageNative` 已经使用了 `type`。
			如果（！附件）{
				如果（文档。文档模式）{
					this.addEventListener( delegateType, focusMappedHandler );
				} 别的 {
					doc.addEventListener（类型，focusMappedHandler，真）；
				}
			}
			dataPriv.set( dataHolder, delegateType, ( 附加 || 0 ) + 1 );
		},
		拆解：函数（）{
			var doc = this.ownerDocument || 这个.document || 这，
				dataHolder = document.documentMode ? 这个：医生，
				attaches = dataPriv.get(dataHolder, delegateType) - 1;

			如果（！附件）{
				如果（文档。文档模式）{
					this.removeEventListener( delegateType, focusMappedHandler );
				} 别的 {
					doc.removeEventListener（类型，focusMappedHandler，真）；
				}
				dataPriv.remove(dataHolder, delegateType);
			} 别的 {
				dataPriv.set(dataHolder, delegateType, attaches);
			}
		}
	};
});

// 使用 mouseover/out 和事件时间检查创建 mouseenter/leave 事件
// 这样事件委托就可以在 jQuery 中工作。
// 对 pointerenter/pointerleave 和 pointerover/pointerout 做同样的事情
//
// 支持：仅限 Safari 7
// Safari 过于频繁地发送 mouseenter；看：
// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
// 错误的描述（它也存在于旧的 Chrome 版本中）。
jQuery.each({
	mouseenter: "鼠标悬停",
	mouseleave: "鼠标移开",
	pointerenter: "指针悬停",
	pointerleave: "指针输出"
}, 函数(原点, 修复) {
	jQuery.event.special[ orig ] = {
		委托类型：修复，
		绑定类型：修复，

		句柄：函数（事件）{
			变种，
				目标=这个，
				related = event.relatedTarget,
				handleObj = event.handleObj;

			// 对于 mouseenter/leave，如果相关对象在目标之外，则调用处理程序。
			// 注意：如果鼠标离开/进入浏览器窗口则没有 relatedTarget
			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
				event.type = handleObj.origType;
				ret = handleObj.handler.apply(this, arguments);
				事件类型=修复；
			}
			返还；
		}
	};
});

jQuery.fn.extend({

	on: function( types, selector, data, fn ) {
		返回（这个，类型，选择器，数据，fn）；
	},
	一：功能（类型，选择器，数据，fn）{
		返回（这个，类型，选择器，数据，fn，1）;
	},
	关闭：功能（类型，选择器，fn）{
		var handleObj，类型；
		如果（类型 && types.preventDefault && types.handleObj）{

			// ( 事件 ) 调度 jQuery.Event
			handleObj = types.handleObj;
			jQuery( types.delegateTarget ).off(
				handleObj.命名空间？
					handleObj.origType + "." + handleObj.命名空间：
					handleObj.origType,
				handleObj.selector,
				handleObj.处理程序
			);
			归还这个；
		}
		如果（typeof类型===“对象”）{

			// ( 类型对象 [, 选择器] )
			对于（输入类型）{
				this.off( type, selector, types[ type ] );
			}
			归还这个；
		}
		如果（选择器===假||类型选择器===“功能”）{

			// ( 类型 [, fn] )
			fn = 选择器；
			选择器=未定义；
		}
		如果（fn ===假）{
			fn = 返回假；
		}
		返回 this.each( 函数() {
			jQuery.event.remove（这个，类型，fn，选择器）;
		});
	}
});


变量

	// 支持：IE <=10 - 11，仅限 Edge 12 - 13
	// 在 IE/Edge 中，在这里使用正则表达式组会导致严重的减速。
	// 请参阅 https://connect.microsoft.com/IE/feedback/details/1736512/
	rnoInnerhtml = /<script|<style|<link/i,

	// checked="checked" 或选中
	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,

	rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g;

// 优先使用 tbody 而不是它的父表来包含新行
函数操作目标（元素，内容）{
	如果（节点名（元素，“表”）&&
		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {

		返回 jQuery( elem ).children( "tbody" )[ 0 ] || 元素;
	}

	返回元素；
}

// 替换/恢复脚本元素的类型属性以进行安全的 DOM 操作
函数 disableScript(elem){
	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
	返回元素；
}
函数 restoreScript(elem){
	如果 ( ( elem.type || "" ).slice( 0, 5 ) === "真/" ) {
		elem.type = elem.type.slice( 5 );
	} 别的 {
		elem.removeAttribute("类型");
	}

	返回元素；
}

函数 cloneCopyEvent（源，目标）{
	var i, l, type, pdataOld, udataOld, udataCur, 事件；

	如果 ( dest.nodeType !== 1 ) {
		返回;
	}

	// 1. 复制私有数据：事件、处理程序等。
	如果（dataPriv.hasData（src））{
		pdataOld = dataPriv.get( src );
		事件 = pdataOld.events;

		如果（事件）{
			dataPriv.remove( dest, "处理事件" );

			for（输入事件）{
				对于 ( i = 0, l = events[ type ].length; i < l; i++ ) {
					jQuery.event.add( dest, type, events[ type ][ i ] );
				}
			}
		}
	}

	// 2. 复制用户数据
	如果（dataUser.hasData（源））{
		udataOld = dataUser.access( src );
		udataCur = jQuery.extend({}, udataOld);

		dataUser.set( dest, udataCur );
	}
}

// 修复 IE 错误，查看支持测试
函数 fixInput（源，目标）{
	var nodeName = dest.nodeName.toLowerCase();

	// 无法保持克隆的复选框或单选按钮的选中状态。
	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
		dest.checked = src.checked;

	// 克隆选项时无法将选中的选项返回到默认选中状态
	} else if ( nodeName === "input" || nodeName === "textarea" ) {
		dest.defaultValue = src.defaultValue;
	}
}

function domManip(collection, args, callback, ignored) {

	// 展平任何嵌套数组
	args = flat( args );

	var fragment, first, scripts, hasScripts, node, doc,
		我 = 0,
		l = collection.length,
		iNoClone = l - 1,
		值 = args[0],
		valueIsFunction = isFunction( 值 );

	// 我们不能在 WebKit 中克隆包含 checked 的节点片段
	如果 ( valueIsFunction ||
			( l > 1 && typeof value === "string" &&
				!support.checkClone && rchecked.test( 值 ) ) ) {
		返回 collection.each( 函数( 索引 ) {
			var self = collection.eq(索引);
			如果（valueIsFunction）{
				args[ 0 ] = value.call( this, index, self.html() );
			}
			domManip（自我，参数，回调，忽略）；
		});
	}

	如果 ( l ) {
		fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored );
		first = fragment.firstChild;

		如果（片段.childNodes.length === 1）{
			片段=第一；
		}

		// 需要新内容或对被忽略的元素感兴趣才能调用回调
		如果（第一个 || 忽略）{
			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
			hasScripts = scripts.length;

			// 对最后一项使用原始片段
			// 而不是第一个，因为它可以结束
			// 在某些情况下被错误清空 (trac-8070)。
			对于（；我<我；我++）{
				节点=片段；

				如果（我！== iNoClone）{
					node = jQuery.clone( node, true, true );

					// 保留对克隆脚本的引用以供以后恢复
					如果（有脚本）{

						// 支持：仅限 Android <=4.0，仅限 PhantomJS 1
						// push.apply(_, arraylike) 在古老的 WebKit 上抛出
						jQuery.merge(脚本，getAll(节点，“脚本”));
					}
				}

				callback.call(collection[i], node, i);
			}

			如果（有脚本）{
				doc = scripts[ scripts.length - 1 ].ownerDocument;

				// 重新启用脚本
				jQuery.map（脚本，restoreScript）；

				// 在第一个文档插入时评估可执行脚本
				for ( i = 0; i < hasScripts; i++ ) {
					节点=脚本[我]；
					如果 ( rscriptType.test( node.type || "" ) &&
						!dataPriv.access( node, "globalEval" ) &&
						jQuery.contains（文档，节点））{

						if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) {

							// 可选的 AJAX 依赖项，但如果不存在则不会运行脚本
							如果（jQuery._evalUrl && !node.noModule）{
								jQuery._evalUrl( node.src, {
									随机数：node.nonce || node.getAttribute( "nonce" )
								}, 文件);
							}
						} 别的 {

							// 展开包含脚本内容的 CDATA 部分。这不应该
							// 需要，因为在 XML 文档中它们已经不可见
							// 检查元素内容，在 HTML 文档中它们没有
							// 意思是我们为了向后兼容保留了这个逻辑。
							// 这将在 4.0 中完全删除。参见 gh-4904。
							DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
						}
					}
				}
			}
		}
	}

	退货收集；
}

功能删除（元素，选择器，keepData）{
	可变节点，
		节点=选择器？jQuery.filter（选择器，元素）：元素，
		我 = 0;

	对于 ( ; ( node = nodes[ i ] ) != null; i++ ) {
		如果（！keepData && node.nodeType === 1）{
			jQuery.cleanData(getAll(节点));
		}

		如果（节点。父节点）{
			如果（keepData && isAttached（节点））{
				setGlobalEval( getAll( 节点, "脚本" ) );
			}
			node.parentNode.removeChild(节点);
		}
	}

	返回元素；
}

jQuery.扩展（{
	htmlPrefilter: function( html ) {
		返回html；
	},

	克隆：函数（elem，dataAndEvents，deepDataAndEvents）{
		变量 i, l, srcElements, destElements,
			clone = elem.cloneNode( true ),
			inPage = isAttached(元素);

		// 修复 IE 克隆问题
		如果（！support.noCloneChecked &&（elem.nodeType === 1 || elem.nodeType === 11）&&
				!jQuery.isXMLDoc(elem)){

			// 出于性能原因，我们在这里避开 jQuery#find：
			// https://jsperf.com/getall-vs-sizzle/2
			destElements = getAll(克隆);
			srcElements = getAll(元素);

			对于 ( i = 0, l = srcElements.length; i < l; i++ ) {
				fixInput( srcElements[ i ], destElements [ i ] );
			}
		}

		// 将事件从原始复制到克隆
		如果（数据和事件）{
			如果（深度数据和事件）{
				源元素 = 源元素 || getAll(元素);
				destElements = destElements || getAll（克隆）；

				对于 ( i = 0, l = srcElements.length; i < l; i++ ) {
					cloneCopyEvent( srcElements[ i ], destElements [ i ] );
				}
			} 别的 {
				克隆复制事件（元素，克隆）；
			}
		}

		// 保存脚本评估历史
		destElements = getAll(克隆，“脚本”);
		如果 ( destElements.length > 0 ) {
			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
		}

		// 返回克隆的集合
		返回克隆；
	},

	cleanData：函数（元素）{
		可变数据，元素，类型，
			特殊 = jQuery.event.special,
			我 = 0;

		对于 ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
			如果（接受数据（元素））{
				如果 ( ( data = elem[ dataPriv.expando ] ) ) {
					如果（数据。事件）{
						对于（输入数据。事件）{
							如果（特殊[类型]）{
								jQuery.event.remove（元素，类型）；

							// 这是避免 jQuery.event.remove 开销的捷径
							} 别的 {
								jQuery.removeEvent(elem, 类型, data.handle);
							}
						}
					}

					// 支持：Chrome <=35 - 45+
					// 赋值 undefined 而不是使用 delete，参见 Data#remove
					elem[ dataPriv.expando ] = undefined;
				}
				如果 (elem[dataUser.expando]){

					// 支持：Chrome <=35 - 45+
					// 赋值 undefined 而不是使用 delete，参见 Data#remove
					elem[ dataUser.expando ] = undefined;
				}
			}
		}
	}
});

jQuery.fn.extend({
	分离：函数（选择器）{
		返回删除（这个，选择器，真）；
	},

	移除：函数（选择器）{
		返回删除（这个，选择器）；
	},

	文本：函数（值）{
		返回访问（这个，函数（值）{
			返回值 === 未定义？
				jQuery.text（这个）：
				this.empty().each( 函数() {
					如果（this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9）{
						this.textContent = 值；
					}
				});
		}, null, 值, arguments.length );
	},

	追加：功能（）{
		返回 domManip（这个，参数，函数（elem）{
			如果（this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9）{
				var target = manipulationTarget(this, elem);
				target.appendChild(元素);
			}
		});
	},

	前置：函数（）{
		返回 domManip（这个，参数，函数（elem）{
			如果（this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9）{
				var target = manipulationTarget(this, elem);
				target.insertBefore( elem, target.firstChild );
			}
		});
	},

	之前：函数（）{
		返回 domManip（这个，参数，函数（elem）{
			如果（this.parentNode）{
				this.parentNode.insertBefore(elem,this);
			}
		});
	},

	之后：函数（）{
		返回 domManip（这个，参数，函数（elem）{
			如果（this.parentNode）{
				this.parentNode.insertBefore( elem, this.nextSibling );
			}
		});
	},

	空：函数（）{
		变量元素，
			我 = 0;

		对于 ( ; ( elem = this[ i ] ) != null; i++ ) {
			如果 (elem.nodeType === 1) {

				// 防止内存泄漏
				jQuery.cleanData(getAll(elem, false));

				// 删除所有剩余的节点
				elem.textContent = "";
			}
		}

		归还这个；
	},

	克隆：函数（dataAndEvents，deepDataAndEvents）{
		dataAndEvents = dataAndEvents == null ？错误：数据和事件；
		deepDataAndEvents = deepDataAndEvents == null ？数据和事件：深度数据和事件；

		返回 this.map( 函数() {
			返回 jQuery.clone（这个，dataAndEvents，deepDataAndEvents）;
		});
	},

	html：函数（值）{
		返回访问（这个，函数（值）{
			var elem = this[ 0 ] || {},
				我 = 0,
				l = this.length;

			如果（值 === 未定义 && elem.nodeType === 1）{
				返回 elem.innerHTML；
			}

			// 看看我们是否可以走捷径，只使用 innerHTML
			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
				!wrapMap[ ( rtagName.exec( 值 ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {

				value = jQuery.htmlPrefilter( value );

				尝试 {
					对于（；我<我；我++）{
						elem = this[ i ] || {};

						// 移除元素节点，防止内存泄漏
						如果 (elem.nodeType === 1) {
							jQuery.cleanData(getAll(elem, false));
							elem.innerHTML = 值；
						}
					}

					元素 = 0;

				// 如果使用 innerHTML 抛出异常，使用 fallback 方法
				} 抓住 (e) {}
			}

			如果（元素）{
				this.empty().append(value);
			}
		}, null, 值, arguments.length );
	},

	替换为：函数（）{
		var 忽略 = [];

		// 进行更改，用新内容替换每个未忽略的上下文元素
		返回 domManip（这个，参数，函数（elem）{
			var parent = this.parentNode;

			if ( jQuery.inArray( this, ignored ) < 0 ) {
				jQuery.cleanData(getAll(this));
				如果（父母）{
					parent.replaceChild(elem, this);
				}
			}

		// 强制回调调用
		}, 忽略）;
	}
});

jQuery.each({
	附加到：“追加”，
	prependTo：“前置”，
	insertBefore: "之前",
	insertAfter: "之后",
	全部替换：“替换为”
}, function(名称, 原文){
	jQuery.fn[ 名称 ] = 函数（选择器）{
		可变元素，
			返回 = [],
			insert = jQuery( 选择器 ),
			最后 = insert.length - 1,
			我 = 0;

		对于（；我<=最后一个；我++）{
			elems = i === 最后一个 ? 这：this.clone（真）；
			jQuery( insert[ i ] )[ original ]( elems );

			// 支持：仅限 Android <=4.0，仅限 PhantomJS 1
			// .get() 因为 push.apply(_, arraylike) 在古老的 WebKit 上抛出
			push.apply(ret, elems.get());
		}

		返回 this.pushStack(ret);
	};
});
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[az%]+$", "i" );

var rcustomProp = /^--/;


var getStyles = 函数（元素）{

		// 支持：仅 IE <=11，Firefox <=30（trac-15098、trac-14150）
		// IE 抛出在弹出窗口中创建的元素
		// FF 同时通过“defaultView.getComputedStyle”抛出框架元素
		var view = elem.ownerDocument.defaultView;

		如果（！查看||！view.opener）{
			查看=窗口；
		}

		返回 view.getComputedStyle( elem );
	};

var swap = function(elem, options, callback) {
	var ret, 名字,
		旧 = {};

	// 记住旧值，并插入新值
	对于（选项中的名称）{
		old[名称] = elem.style[名称];
		elem.style[名称] = 选项[名称];
	}

	ret = callback.call(elem);

	// 还原旧值
	对于（选项中的名称）{
		elem.style[ 名称 ] = old[ 名称 ];
	}

	返还；
};


var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );



（ 功能（） {

	// 执行 pixelPosition 和 boxSizingReliable 测试只需要一个布局
	// 所以它们同时执行以保存第二次计算。
	函数 computeStyleTests() {

		// 这是一个单例，我们只需要执行一次
		如果（！div）{
			返回;
		}

		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
			“顶部边距：1px；填充：0；边框：0”；
		div.style.cssText =
			“位置：相对；显示：块；框大小：边框框；溢出：滚动；” +
			“边距：自动；边框：1px；填充：1px；” +
			“宽度：60%；顶部：1%”；
		documentElement.appendChild(容器).appendChild(div);

		var divStyle = window.getComputedStyle( div );
		pixelPositionVal = divStyle.top !== "1%";

		// 支持：仅限 Android 4.0 - 4.3，Firefox <=3 - 44
		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;

		// 支持：仅限 Android 4.0 - 4.3，Safari <=9.1 - 10.1，iOS <=7.0 - 9.3
		// 有些样式返回百分比值，即使它们不应该
		div.style.right = "60%";
		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;

		// 支持：仅限 IE 9 - 11
		// 检测 box-sizing:border-box 元素内容尺寸的误报
		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;

		// 支持：仅 IE 9
		// 检测溢出：滚动扭曲 (gh-3699)
		// 支持：Chrome <=64
		// 当缩放影响 offsetWidth (gh-4029) 时不要上当受骗
		div.style.position = "绝对";
		scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;

		documentElement.removeChild(容器);

		// 使 div 无效，这样它就不会存储在内存中，并且
		// 这也是检查已经执行的标志
		股利 = 空;
	}

	函数 roundPixelMeasures（测量）{
		返回 Math.round(parseFloat(measure));
	}

	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
		reliableTrDimensionsVal, reliableMarginLeftVal,
		container = document.createElement( "div" ),
		div = document.createElement( "div" );

	// 在有限的（非浏览器）环境中尽早完成
	如果（！div.style）{
		返回;
	}

	// 支持：仅限 IE <=9 - 11
	// 克隆元素的样式影响克隆的源元素 (trac-8908)
	div.style.backgroundClip = "内容框";
	div.cloneNode( true ).style.backgroundClip = "";
	support.clearCloneStyle = div.style.backgroundClip === "内容框";

	jQuery.extend( 支持, {
		boxSizingReliable：函数（）{
			计算样式测试（）；
			返回 boxSizingReliableVal；
		},
		像素框样式：函数（）{
			计算样式测试（）；
			返回 pixelBoxStylesVal；
		},
		像素位置：函数（）{
			计算样式测试（）；
			返回像素位置值；
		},
		reliableMarginLeft: function() {
			计算样式测试（）；
			返回 reliableMarginLeftVal；
		},
		滚动框大小：函数（）{
			计算样式测试（）；
			返回 scrollboxSizeVal；
		},

		// 支持：IE 9 - 11+，Edge 15 - 18+
		// IE/Edge 误报具有宽度/高度的表格行的 `getComputedStyle`
		// 在 CSS 中设置，而 `offset*` 属性报告正确的值。
		// IE 9 中的行为比新版本更微妙 & 它通过了
		// 这个测试的一些版本；确保不要让它通过那里！
		//
		// 支持：Firefox 70+
		// 只有 Firefox 包括边框宽度
		// 在计算维度中。(gh-4529)
		reliableTrDimensions: 函数() {
			变量表，tr，trChild，trStyle；
			如果 (reliableTrDimensionsVal == null) {
				table = document.createElement( "table" );
				tr = document.createElement( "tr" );
				trChild = document.createElement( "div" );

				table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
				tr.style.cssText = "边框:1px 实心";

				// 支持：Chrome 86+
				// 通过 cssText 设置的高度不会被应用。
				// 计算出的高度然后返回为 0。
				tr.style.height = "1px";
				trChild.style.height = "9px";

				// 支持：Android 8 Chrome 86+
				// 在我们的 bodyBackground.html iframe 中，
				// 所有 div 元素的显示设置为“inline”，
				// 这只会在 Android 8 Chrome 86 中导致问题。
				// 确保 div 是 display: block
				// 绕过这个问题。
				trChild.style.display = "方块";

				文档元素
					.appendChild(表)
					.appendChild(tr)
					.appendChild( trChild );

				trStyle = window.getComputedStyle( tr );
				reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +
					parseInt( trStyle.borderTopWidth, 10 ) +
					parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;

				documentElement.removeChild(表);
			}
			返回可靠的 TrDimensionsVal；
		}
	});
} )();


function curCSS( elem, name, computed ) {
	可变宽度，最小宽度，最大宽度，ret，
		isCustomProp = rcustomProp.test(名称),

		// 支持：Firefox 51+
		// 在以某种方式计算之前检索样式
		// 修复获取错误值的问题
		// 在分离的元素上
		样式 = elem.style;

	计算=计算|| getStyles(元素);

	// 需要 getPropertyValue 用于：
	// .css('filter')（仅限 IE 9，trac-12537）
	// .css('--customProperty) (gh-3144)
	如果（计算）{

		// 支持：IE <=9 - 11+
		// IE 只支持 `getPropertyValue` 中的 `"float"`；在计算样式中
		// 它只能作为 `"cssFloat"` 使用。我们不再修改属性
		// 发送给 `.css()` 除了 camelCasing，所以我们需要检查两者。
		// 通常，这会造成行为上的差异：如果
		// `getPropertyValue` 返回空字符串，返回值
		// 通过 `.css()` 将是 `undefined`。这通常适用于
		// 断开连接的元素。然而，在 IE 中甚至断开连接的元素
		// 没有样式，为 `getPropertyValue( "float" )` 返回 `"none"`
		ret = computed.getPropertyValue(名称)|| 计算[名称]；

		如果（isCustomProp && ret）{

			// 支持：Firefox 105+, Chrome <=105+
			// 规范要求为自定义属性修剪空格 (gh-4926)。
			// Firefox 只修剪前导空格。Chrome 刚刚崩溃
			// 前导和尾随空格到一个空格。
			//
			// 如果返回空字符串，则回退到 `undefined`。
			// 这会折叠一个缺少的定义，其中包含已定义的属性
			// 并设置为空字符串，但没有标准 API
			// 允许我们在不影响性能的情况下区分它们
			// 并返回 `undefined` 与旧的 jQuery 一致。
			//
			// rtrimCSS 处理 U+000D CARRIAGE RETURN 和 U+000C FORM FEED
			// 作为空格，而 CSS 不是，但这不是问题
			// 因为 CSS 预处理将它们替换为 U+000A LINE FEED
			//（*是* CSS 空格）
			// https://www.w3.org/TR/css-syntax-3/#input-preprocessing
			ret = ret.replace( rtrimCSS, "$1" ) || 不明确的;
		}

		如果 ( ret === "" && !isAttached( elem ) ) {
			ret = jQuery.style(元素, 名称);
		}

		// 向“Dean Edwards 的精彩黑客”致敬
		// Android 浏览器返回某些值的百分比，
		// 但宽度似乎是可靠的像素。
		// 这违反了 CSSOM 草案规范：
		// https://drafts.c​​sswg.org/cssom/#resolved-values
		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {

			// 记住原始值
			宽度 = 样式.宽度；
			minWidth = style.minWidth;
			最大宽度 = 样式.最大宽度；

			// 放入新值以得到计算值
			style.minWidth = style.maxWidth = style.width = ret;
			ret = computed.width;

			// 恢复改变的值
			样式.width = 宽度；
			style.minWidth = 最小宽度；
			style.maxWidth = 最大宽度；
		}
	}

	返回 ret !== undefined ？

		// 支持：仅限 IE <=9 - 11
		// IE 以整数形式返回 zIndex 值。
		返回+“”：
		退役；
}


函数 addGetHookIf(conditionFn, hookFn){

	// 定义钩子，我们将在第一次运行时检查它是否真的需要。
	返回 {
		得到：函数（）{
			如果 ( conditionFn() ) {

				// 不需要钩子（或者不可能使用它，因为
				// 缺少依赖），删除它。
				删除this.get；
				返回;
			}

			// 需要钩子；重新定义它，以便不再执行支持测试。
			返回 (this.get = hookFn).apply(this, arguments);
		}
	};
}


var cssPrefixes = [ "Webkit", "Moz", "ms" ],
	emptyStyle = document.createElement( "div" ).style,
	vendorProps = {};

// 返回一个供应商前缀的属性或未定义的
函数 vendorPropName（名称）{

	// 检查供应商前缀名称
	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
		i = cssPrefixes.length;

	当我 -  ） {
		name = cssPrefixes[ i ] + capName;
		如果（名称为空样式）{
			返回名称；
		}
	}
}

// 返回一个可能映射的 jQuery.cssProps 或供应商前缀属性
函数 finalPropName(名称){
	var final = jQuery.cssProps[名称] || vendorProps[ 名称 ];

	如果（最终）{
		返回决赛；
	}
	如果（名称为空样式）{
		返回名称；
	}
	返回 vendorProps[名称] = vendorPropName(名称)|| 姓名;
}


变量

	// 如果显示为无或以表格开头，则可交换
	// 除了“table”、“table-cell”或“table-caption”
	// 请在此处查看显示值：https://developer.mozilla.org/en-US/docs/CSS/display
	rdisplayswap = /^(无|表(?!-c[ea]).+)/,
	cssShow = { 位置：“绝对”，可见性：“隐藏”，显示：“块”}，
	cssNormalTransform = {
		字母间距：“0”，
		字体粗细：“400”
	};

函数 setPositiveNumber(_elem, value, subtract) {

	// 任何相对 (+/-) 值已经被
	//此时归一化
	var matches = rcssNum.exec( 值 );
	返回火柴？

		// 防止未定义的“减去”，例如，当在 cssHooks 中使用时
		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) ：
		价值;
}

function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) {
	var i = dimension === “宽度” ? 1 : 0,
		额外 = 0,
		增量 = 0,
		保证金增量 = 0;

	// 可能不需要调整
	如果（盒子===（isBorderBox？“边框”：“内容”））{
		返回 0；
	}

	对于（；我<4；我+=2）{

		// 两种盒模型都排除边距
		// 分别计算 margin delta 以仅在 scroll gutter 调整后添加它。
		// 这是使负边距与 `outerHeight( true )` (gh-3982) 一起工作所必需的。
		如果（框===“保证金”）{
			marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
		}

		// 如果我们带着内容框到达这里，我们正在寻找“填充”或“边框”或“边距”
		如果（！isBorderBox）{

			// 添加填充
			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );

			// 对于“border”或“margin”，添加边框
			如果（盒子！==“填充”）{
				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );

			// 但是仍然要跟踪它
			} 别的 {
				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
			}

		// 如果我们到达这里有一个边框框（内容 + 填充 + 边框），我们正在寻找“内容”或
		// “填充”或“边距”
		} 别的 {

			// 对于“内容”，减去填充
			如果（盒子===“内容”）{
				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
			}

			// 对于“content”或“padding”，减去边框
			如果（盒子！==“保证金”）{
				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
			}
		}
	}

	// 通过提供 computedVal 请求时考虑正内容框滚动槽
	如果（！isBorderBox && computedVal >= 0）{

		// offsetWidth/offsetHeight 是内容、填充、滚动条和边框的四舍五入和
		// 假设滚动条为整数，减去其余部分并向下取整
		delta += Math.max( 0, Math.ceil(
			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
			计算值 -
			三角洲 -
			额外的 -
			0.5

		// 如果 offsetWidth/offsetHeight 未知，那么我们无法确定内容框滚动条
		// 使用明确的零来避免 NaN (gh-3964)
		) ) || 0;
	}

	返回 delta + marginDelta；
}

函数 getWidthOrHeight（元素，维度，额外）{

	// 从计算样式开始
	var styles = getStyles(元素),

		// 为避免强制回流，仅在需要时获取 boxSizing (gh-4322)。
		// 伪造内容框，直到我们知道它需要知道真实值。
		boxSizingNeeded = !support.boxSizingReliable() || 额外的，
		isBorderBox = boxSizingNeeded &&
			jQuery.css( elem, "boxSizing", false, styles ) === "边框框",
		valueIsBorderBox = isBorderBox,

		val = curCSS(元素、尺寸、样式),
		offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );

	// 支持：Firefox <=54
	// 酌情返回混杂的非像素值或假装无知。
	如果（rnumnonpx.test（val））{
		如果（！额外）{
			返回值；
		}
		val = "自动";
	}


	// 支持：仅限 IE 9 - 11
	// 当盒子大小不可靠时使用 offsetWidth/offsetHeight。
	// 在这些情况下，可以相信计算值是边框框。
	如果 ( ( !support.boxSizingReliable() && isBorderBox ||

		// 支持：IE 10 - 11+，Edge 15 - 18+
		// IE/Edge 误报具有宽度/高度的表格行的 `getComputedStyle`
		// 在 CSS 中设置，而 `offset*` 属性报告正确的值。
		// 有趣的是，在某些情况下 IE 9 不会遇到此问题。
		!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||

		// 当值为“auto”时回落到 offsetWidth/offsetHeight
		// 这发生在没有显式设置的内联元素上 (gh-3571)
		val === “自动” ||

		// 支持：仅限 Android <=4.1 - 4.3
		// 还使用 offsetWidth/offsetHeight 来处理误报的内联尺寸 (gh-3602)
		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&

		// 确保元素可见且已连接
		elem.getClientRects().length ) {

		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "边框框";

		// 如果可用，offsetWidth/offsetHeight 近似边框尺寸。
		// 在不可用的情况下（例如，SVG），假设不可靠的框大小并解释
		// 检索值作为内容框维度。
		valueIsBorderBox = 元素中的 offsetProp；
		如果（值IsBorderBox）{
			val = elem[ offsetProp ];
		}
	}

	// 规范化 "" 和自动
	val = parseFloat( val ) || 0;

	// 调整元素的盒子模型
	返回（值+
		boxModel调整（
			元素，
			方面，
			额外 || （isBorderBox？“边框”：“内容”），
			valueIsBorderBox,
			风格，

			// 提供当前计算的大小以请求滚动间距计算 (gh-3589)
			值
		)
	) + "像素";
}

jQuery.扩展（{

	// 添加样式属性挂钩以覆盖默认值
	// 获取和设置样式属性的行为
	CSSHooks：{
		不透明度：{
			得到：函数（元素，计算）{
				如果（计算）{

					// 我们应该总是从不透明度中得到一个数字
					var ret = curCSS( elem, "透明度" );
					返回 ret === "" ？“1”：退役；
				}
			}
		}
	},

	// 不要自动将“px”添加到这些可能没有单位的属性
	CSS 编号：{
		动画迭代次数：真，
		纵横比：真，
		borderImageSlice: 是的，
		列数：真，
		弹性增长：真实的，
		弹性收缩：真，
		字体粗细：真，
		网格区域：真实的，
		网格列：真，
		gridColumnEnd：真，
		gridColumnStart：真，
		网格行：真实的，
		gridRowEnd：真，
		gridRowStart：真，
		行高：真，
		不透明度：真实，
		订单：真实，
		孤儿：真的，
		规模：真实，
		寡妇：是的，
		zIndex：真实，
		缩放：真实，

		// SVG相关
		填充不透明度：真，
		floodOpacity：真实，
		停止不透明度：真，
		strokeMiterlimit：真，
		描边不透明度：真
	},

	// 添加您之前希望修复其名称的属性
	// 设置或获取值
	cssProps: {},

	// 获取和设置 DOM 节点上的样式属性
	样式：函数（元素、名称、值、额外）{

		// 不要在文本和注释节点上设置样式
		如果 (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
			返回;
		}

		// 确保我们使用的是正确的名称
		var ret，类型，钩子，
			origName = camelCase( 名字 ),
			isCustomProp = rcustomProp.test(名称),
			样式 = elem.style;

		// 确保我们使用的是正确的名称。我们不
		// 如果它是 CSS 自定义属性，则要查询该值
		// 因为它们是用户定义的。
		如果（！isCustomProp）{
			name = finalPropName( origName );
		}

		// 获取前缀版本的钩子，然后是无前缀版本
		hooks = jQuery.cssHooks[名称] || jQuery.cssHooks[ origName ];

		// 检查我们是否设置了一个值
		如果（价值！==未定义）{
			类型 = 类型值；

			// 将“+=”或“-=”转换为相对数字 (trac-7345)
			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
				value = adjustCSS( elem, name, ret );

				// 修复错误 trac-9237
				类型=“数字”；
			}

			// 确保未设置 null 和 NaN 值 (trac-7116)
			如果（值==空||值！==值）{
				返回;
			}

			// 如果传入数字，则添加单位（某些 CSS 属性除外）
			// 当我们只自动附加时，可以在 jQuery 4.0 中删除 isCustomProp 检查
			// "px" 到一些硬编码值。
			如果（类型===“数字”&&！isCustomProp）{
				值 += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
			}

			// background-* 属性影响原始克隆的值
			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
				样式[名称] = "继承";
			}

			// 如果提供了一个钩子，使用那个值，否则只设置指定的值
			if ( !hooks || !( "set" in hooks ) ||
				( value = hooks.set( elem, value, extra ) ) !== undefined ) {

				如果（isCustomProp）{
					style.setProperty(名称, 值);
				} 别的 {
					样式[名称] = 值；
				}
			}

		} 别的 {

			// 如果提供了钩子，则从那里获取非计算值
			if ( hooks && "get" in hooks &&
				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {

				返还；
			}

			// 否则只从样式对象中获取值
			返回样式[名称]；
		}
	},

	css: function(elem, name, extra, styles) {
		var val, num, 钩子,
			origName = camelCase( 名字 ),
			isCustomProp = rcustomProp.test(名称);

		// 确保我们使用的是正确的名称。我们不
		// 如果它是 CSS 自定义属性，则要修改该值
		// 因为它们是用户定义的。
		如果（！isCustomProp）{
			name = finalPropName( origName );
		}

		// 尝试带前缀的名称后跟无前缀的名称
		hooks = jQuery.cssHooks[名称] || jQuery.cssHooks[ origName ];

		// 如果提供了钩子，则从那里获取计算值
		if ( hooks && "get" in hooks ) {
			val = hooks.get(elem, true, extra);
		}

		// 否则，如果存在获取计算值的方法，则使用该方法
		如果（ val === 未定义）{
			val = curCSS(元素、名称、样式);
		}

		// 将“正常”转换为计算值
		if ( val === "normal" && name in cssNormalTransform ) {
			val = cssNormalTransform[名称];
		}

		// 如果强制或提供了限定符，则设为数字并且 val 看起来是数字
		如果（额外===“”||额外）{
			num = parseFloat( val );
			返回额外的===真|| 是有限的（数字）？编号 || 0：值；
		}

		返回值；
	}
});

jQuery.each( [ "高度", "宽度" ], function( _i, 维度) {
	jQuery.cssHooks[维度] = {
		得到：函数（元素，计算，额外）{
			如果（计算）{

				// 某些元素可以有尺寸信息，如果我们不可见地显示它们
				// 但它必须有一个当前的显示样式
				返回 rdisplayswap.test(jQuery.css(elem, "display") ) &&

					// 支持：Safari 8+
					// Safari 中的表格列具有非零偏移宽度和零
					// getBoundingClientRect().width 除非显示改变。
					// 支持：仅限 IE <=11
					// 在断开连接的节点上运行 getBoundingClientRect
					// 在 IE 中抛出错误。
					（ !elem.getClientRects().length || !elem.getBoundingClientRect().width ）？
					交换（元素，cssShow，函数（）{
						返回 getWidthOrHeight（元素，维度，额外）；
					}）：
					getWidthOrHeight（元素，尺寸，额外）;
			}
		},

		设置：函数（元素，值，额外）{
			变种匹配，
				样式 = getStyles(元素),

				// 只有在测试有可能失败时才读取 styles.position
				// 避免强制回流。
				scrollboxSizeBuggy = !support.scrollboxSize() &&
					styles.position === "绝对",

				// 为避免强制回流，仅在需要时获取 boxSizing (gh-3991)
				boxSizingNeeded = scrollboxSizeBuggy || 额外的，
				isBorderBox = boxSizingNeeded &&
					jQuery.css( elem, "boxSizing", false, styles ) === "边框框",
				减去=额外？
					boxModel调整（
						元素，
						方面，
						额外的，
						是边框框，
						样式
					）：
					0;

			// 通过比较 offset* 和 computed and
			// 伪造内容框以获得边框和填充 (gh-3699)
			如果（isBorderBox && scrollboxSizeBuggy）{
				减去 -= Math.ceil(
					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
					parseFloat(样式[尺寸])-
					boxModelAdjustment(elem, dimension, "border", false, styles ) -
					0.5
				);
			}

			// 如果需要调整值，则转换为像素
			如果（减去&&（匹配= rcssNum.exec（值））&&
				（匹配[3]||“px”）！==“px”）{

				elem.style[ 维度 ] = 值；
				value = jQuery.css(元素,维度);
			}

			返回 setPositiveNumber（元素，值，减去）；
		}
	};
});

jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
	函数（元素，计算）{
		如果（计算）{
			返回（parseFloat（curCSS（elem，“marginLeft”））||
				elem.getBoundingClientRect().left -
					swap( elem, { marginLeft: 0 }, function() {
						返回 elem.getBoundingClientRect().left;
					})
			) + "像素";
		}
	}
);

// 这些钩子被 animate 用来扩展属性
jQuery.each({
	利润： ””，
	填充：“”，
	边框：“宽度”
}, 函数(前缀, 后缀) {
	jQuery.cssHooks[ 前缀 + 后缀 ] = {
		展开：函数（值）{
			变种我= 0，
				展开 = {},

				// 如果不是字符串，则假定为单个数字
				部分 = typeof 值 === “字符串”？value.split( " " ) : [ 值 ];

			对于（；我<4；我++）{
				扩展[前缀+cssExpand[i]+后缀]=
					部分[我] || 部分 [ i - 2 ] || 零件[0]；
			}

			返回扩展；
		}
	};

	如果（前缀！==“保证金”）{
		jQuery.cssHooks[前缀+后缀].set = setPositiveNumber;
	}
});

jQuery.fn.extend({
	CSS：函数（名称，值）{
		返回访问（这个，函数（元素，名称，值）{
			变种风格，len，
				地图 = {},
				我 = 0;

			如果（Array.isArray（名称））{
				样式 = getStyles(元素);
				len = 名称.长度；

				对于（；我 < 长度；我++）{
					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
				}

				返回地图；
			}

			返回值 !== 未定义？
				jQuery.style（元素，名称，值）：
				jQuery.css(元素, 名称);
		}, 名称, 值, arguments.length > 1 );
	}
});


功能吐温（元素，选项，道具，结束，缓动）{
	返回新的 Tween.prototype.init( elem, options, prop, end, easing );
}
jQuery.Tween = 吐温;

Tween.prototype = {
	构造函数：吐温，
	init: function(elem, options, prop, end, easing, unit) {
		this.elem = elem;
		这个.prop = prop;
		this.easing = 缓动 || jQuery.easing._default;
		this.options = 选项；
		this.start = this.now = this.cur();
		this.end = 结束；
		this.unit = 单位 || ( jQuery.cssNumber[ prop ] ? "" : "px" );
	},
	当前：函数（）{
		var hooks = Tween.propHooks[ this.prop ];

		返回钩子 && hooks.get ？
			hooks.get（这个）：
			Tween.propHooks._default.get( 这个 );
	},
	运行：函数（百分比）{
		变轻松，
			hooks = Tween.propHooks[ this.prop ];

		如果（this.options.duration）{
			this.pos = eased = jQuery.easing[ this.easing ](
				百分比，this.options.duration * 百分比，0、1，this.options.duration
			);
		} 别的 {
			this.pos = eased = 百分比；
		}
		this.now = ( this.end - this.start ) * eased + this.start;

		如果（this.options.step）{
			this.options.step.call(this.elem,this.now,this);
		}

		如果（钩子 && hooks.set）{
			hooks.set(这个);
		} 别的 {
			Tween.propHooks._default.set( 这个 );
		}
		归还这个；
	}
};

Tween.prototype.init.prototype = Tween.prototype;

Tween.propHooks = {
	_默认： {
		得到：功能（吐温）{
			变量结果；

			// 当元素不是 DOM 元素时，直接使用元素的属性，
			// 或者当不存在匹配的样式属性时。
			如果 ( tween.elem.nodeType !== 1 ||
				tween.elem[ tween.prop ] != null && tween.elem.style [ tween.prop ] == null ) {
				返回 tween.elem[ tween.prop ];
			}

			// 将空字符串作为第三个参数传递给 .css 将自动
			// 如果解析失败，尝试 parseFloat 并回退到字符串。
			// 诸如“10px”之类的简单值被解析为 Float；
			// 像“rotate(1rad)”这样的复杂值按原样返回。
			结果 = jQuery.css( tween.elem, tween.prop, "" );

			// 空字符串、null、undefined 和 "auto" 被转换为 0。
			返回！结果|| 结果===“自动”？0：结果；
		},
		设置：函数（吐温）{

			// 使用 step hook 进行反向兼容。
			// 如果它存在则使用 cssHook。
			// 如果可用，请使用 .style 并在可用时使用普通属性。
			如果 (jQuery.fx.step[tween.prop]){
				jQuery.fx.step[ tween.prop ]( tween );
			} else if ( tween.elem.nodeType === 1 && (
				jQuery.cssHooks[ tween.prop ] ||
					tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
			} 别的 {
				tween.elem[ tween.prop ] = tween.now;
			}
		}
	}
};

// 支持：仅限 IE <=9
// 基于恐慌的方法在断开连接的节点上设置事物
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
	设置：函数（吐温）{
		如果（tween.elem.nodeType && tween.elem.parentNode）{
			tween.elem[ tween.prop ] = tween.now;
		}
	}
};

jQuery.easing = {
	线性：函数（p）{
		返回 p;
	},
	摆动：函数（p）{
		返回 0.5 - Math.cos( p * Math.PI ) / 2;
	},
	_default：“摆动”
};

jQuery.fx = Tween.prototype.init;

// 向后兼容 <1.8 扩展点
jQuery.fx.step = {};




变量
	fxNow，进行中，
	rfxtypes = /^(?:toggle|show|hide)$/,
	rrun = /queueHooks$/;

功能时间表（）{
	如果（进行中）{
		if ( document.hidden === false && window.requestAnimationFrame ) {
			window.requestAnimationFrame(时间表);
		} 别的 {
			window.setTimeout( schedule, jQuery.fx.interval );
		}

		jQuery.fx.tick();
	}
}

// 同步创建的动画会同步运行
函数 createFxNow() {
	window.setTimeout(函数(){
		fxNow = 未定义；
	});
	返回 ( fxNow = Date.now() );
}

// 生成参数以创建标准动画
函数 genFx（类型，includeWidth）{
	变种，
		我 = 0,
		属性={高度：类型}；

	// 如果我们包含宽度，step 值为 1 来做所有的 cssExpand 值，
	// 否则 step 值为 2 以跳过 Left 和 Right
	includeWidth = includeWidth ? 1 : 0;
	对于 ( ; i < 4; i += 2 - includeWidth ) {
		which = cssExpand[ i ];
		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
	}

	如果（包含宽度）{
		attrs.opacity = attrs.width = 类型；
	}

	返回属性；
}

函数 createTween（值，道具，动画）{
	吐温变量，
		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
		指数 = 0,
		length = collection.length;
	for (; index < length; index++) {
		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {

			// 我们完成了这个属性
			返回补间；
		}
	}
}

函数 defaultPrefilter( elem, props, opts ) {
	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, 显示,
		isBox = 属性中的“宽度” || 道具中的“高度”，
		动画=这个，
		原 = {},
		样式 = elem.style,
		hidden = elem.nodeType && isHiddenWithinTree( elem ),
		dataShow = dataPriv.get( elem, "fxshow" );

	// 队列跳过动画劫持 fx 挂钩
	如果（！opts.queue）{
		hooks = jQuery._queueHooks( elem, "fx" );
		如果 (hooks.unqueued == null) {
			hooks.unqueued = 0;
			oldfire = hooks.empty.fire;
			hooks.empty.fire = function() {
				如果（！hooks.unqueued）{
					旧火（）；
				}
			};
		}
		hooks.unqueued++;

		anim.always(函数(){

			// 确保在完成之前调用完整的处理程序
			anim.always(函数(){
				hooks.unqueued--;
				if ( !jQuery.queue( elem, "fx" ).length ) {
					hooks.empty.fire();
				}
			});
		});
	}

	// 检测显示/隐藏动画
	对于（道具中的道具）{
		价值=道具[道具];
		如果（rfxtypes.test（值））{
			删除 props[ prop ];
			切换=切换|| 价值===“切换”；
			如果（价值===（隐藏？“嗨德”：“显示”））{

				// 如果这是一个“表演”并且假装隐藏
				// 仍然有来自停止显示/隐藏的数据
				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
					隐藏=真；

				// 忽略所有其他无操作显示/隐藏数据
				} 别的 {
					继续;
				}
			}
			orig[ 道具 ] = dataShow && dataShow[ 道具 ] || jQuery.style(元素, 道具);
		}
	}

	// 如果这是像 .hide().hide() 这样的空操作，则退出
	propTween = !jQuery.isEmptyObject(道具);
	如果 (!propTween && jQuery.isEmptyObject( orig ) ) {
		返回;
	}

	// 在框动画期间限制“溢出”和“显示”样式
	如果（isBox && elem.nodeType === 1）{

		// 支持：IE <=9 - 11，Edge 12 - 15
		// 记录所有 3 个溢出属性，因为 IE 不会推断简写
		// 来自相同值的 overflowX 和 overflowY 以及 Edge 只是镜像
		// 那里的 overflowX 值。
		opts.overflow = [ style.overflow, style.overflowX, style.overflowY];

		// 识别显示类型，优先使用旧的显示/隐藏数据而不是 CSS 级联
		restoreDisplay = dataShow && dataShow.display;
		如果（恢复显示==空）{
			restoreDisplay = dataPriv.get(elem, "display");
		}
		display = jQuery.css( elem, "display" );
		如果（显示===“无”）{
			如果（恢复显示）{
				显示=恢复显示；
			} 别的 {

				// 通过临时强制可见性获取非空值
				showHide( [ elem ], true );
				恢复显示 = elem.style.display || 恢复显示；
				display = jQuery.css( elem, "display" );
				showHide( [ 元素 ] );
			}
		}

		// 将内联元素动画化为内联块
		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
			如果（jQuery.css（elem，“浮动”）===“无”）{

				// 在纯显示/隐藏动画结束时恢复原始显示值
				如果（！propTween）{
					anim.done(函数(){
						style.display = restoreDisplay;
					});
					如果（恢复显示==空）{
						显示 = 样式.显示；
						restoreDisplay = 显示 === “无”？““ ： 展示;
					}
				}
				style.display = "内联块";
			}
		}
	}

	如果（选择溢出）{
		style.overflow = "隐藏";
		anim.always(函数(){
			style.overflow = opts.overflow[0];
			style.overflowX = opts.overflow[1];
			style.overflowY = opts.overflow[2];
		});
	}

	// 实现显示/隐藏动画
	propTween = false;
	for (prop in orig) {

		// 此元素动画的一般显示/隐藏设置
		如果（！propTween）{
			如果（数据显示）{
				如果（数据显示中的“隐藏”）{
					隐藏 = dataShow.hidden;
				}
			} 别的 {
				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
			}

			// 为切换存储隐藏/可见，以便 `.stop().toggle()` “反转”
			如果（切换）{
				dataShow.hidden = !hidden;
			}

			// 在动画之前显示元素
			如果（隐藏）{
				showHide( [ elem ], true );
			}

			/* eslint-disable no-loop-func */

			anim.done(函数(){

				/* eslint-enable no-loop-func */

				// “隐藏”动画的最后一步实际上是隐藏元素
				如果（！隐藏）{
					showHide( [ 元素 ] );
				}
				dataPriv.remove(elem, "fxshow");
				for (prop in orig) {
					jQuery.style( elem, prop, orig[ prop ] );
				}
			});
		}

		// 每个属性设置
		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
		如果（！（数据显示中的道具））{
			dataShow[ prop ] = propTween.start;
			如果（隐藏）{
				propTween.end = propTween.start;
				propTween.start = 0;
			}
		}
	}
}

function propFilter( props, specialEasing ) {
	var index, name, easing, value, hooks;

	// camelCase, specialEasing 和 expand cssHook pass
	对于（道具中的索引）{
		name = camelCase( 索引 );
		easing = specialEasing[名称];
		价值=道具[指数];
		如果（Array.isArray（价值））{
			宽松=价值[1]；
			value = props[ index ] = value[ 0 ];
		}

		如果（索引！==名称）{
			道具[名称] = 价值；
			删除道具[索引]；
		}

		hooks = jQuery.cssHooks[名称];
		如果（挂钩 && 在挂钩中“展开”）{
			value = hooks.expand(value);
			删除道具[名称]；

			// 不完全是 $.extend，这不会覆盖现有的密钥。
			// 重用 'index' 因为我们有正确的“名字”
			对于（值中的索引）{
				if ( !( props 中的索引 ) ) {
					props[ 索引 ] = 值 [ 索引 ];
					specialEasing[ index ] = 缓动；
				}
			}
		} 别的 {
			specialEasing[ 名称 ] = 缓动；
		}
	}
}

功能动画（元素，属性，选项）{
	可变结果，
		停下来，
		指数 = 0,
		length = Animation.prefilters.length,
		deferred = jQuery.Deferred().always( 函数() {

			// 不要匹配 :animated 选择器中的元素
			删除 tick.elem；
		}),
		滴答=功能（）{
			如果（停止）{
				返回假；
			}
			var currentTime = fxNow || 创建FxNow(),
				剩余 = Math.max( 0, animation.startTime + animation.duration - currentTime ),

				// 支持：仅限 Android 2.3
				// 古老的崩溃错误不允许我们使用 `1 - ( 0.5 || 0 )` (trac-12497)
				temp = 剩余 / animation.duration || 0,
				百分比 = 1 - 温度，
				指数 = 0,
				length = animation.tweens.length;

			for (; index < length; index++) {
				animation.tweens[ index ].run( percent );
			}

			deferred.notifyWith( elem, [ animation, percent, remaining ] );

			// 如果还有更多事情要做，yield
			如果（百分比 < 1 && 长度）{
				返回剩余；
			}

			// 如果这是一个空动画，合成一个最终的进度通知
			如果（！长度）{
				deferred.notifyWith( elem, [ 动画, 1, 0 ] );
			}

			// 解析动画并报告其结论
			deferred.resolveWith(元素, [动画]);
			返回假；
		},
		动画 = deferred.promise( {
			元素：元素，
			道具：jQuery.extend（{}，属性），
			选择：jQuery.extend( true, {
				特别宽松：{}，
				缓动：jQuery.easing._default
			}， 选项 ），
			originalProperties：属性，
			originalOptions：选项，
			开始时间：fxNow || 创建FxNow(),
			持续时间：options.duration，
			补间：[]，
			createTween: function(prop, end) {
				var tween = jQuery.Tween( elem, animation.opts, prop, end,
					animation.opts.specialEasing[ prop ] || 动画.opts.easing );
				animation.tweens.push(tween);
				返回补间；
			},
			停止：功能（gotoEnd）{
				变量索引 = 0,

					// 如果我们要结束，我们想要运行所有补间
					// 否则我们跳过这部分
					长度=转到结束？动画.tweens.length : 0;
				如果（停止）{
					归还这个；
				}
				停止=真；
				for (; index < length; index++) {
					animation.tweens[ index ].run( 1 );
				}

				// 当我们播放最后一帧时解析；否则，拒绝
				如果（转到结束）{
					deferred.notifyWith( elem, [ 动画, 1, 0 ] );
					deferred.resolveWith( elem, [ animation, gotoEnd ] );
				} 别的 {
					deferred.rejectWith( elem, [ animation, gotoEnd ] );
				}
				归还这个；
			}
		}),
		道具 = animation.props;

	propFilter( props, animation.opts.specialEasing );

	for (; index < length; index++) {
		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
		如果（结果）{
			如果（isFunction（result.stop））{
				jQuery._queueHooks(animation.elem, animation.opts.queue).stop =
					结果.停止.绑定（结果）；
			}
			返回结果；
		}
	}

	jQuery.map(道具, createTween, 动画);

	如果（isFunction（animation.opts.start））{
		animation.opts.start.call(elem, animation);
	}

	// 附加来自选项的回调
	动画片
		.progress(动画.opts.progress)
		.done(动画.opts.done, animation.opts.complete)
		.fail(动画.opts.fail)
		.always(动画.opts.always);

	jQuery.fx.timer(
		jQuery.extend(打勾，{
			元素：元素，
			动画：动画，
			队列：animation.opts.queue
		})
	);

	返回动画；
}

jQuery.Animation = jQuery.extend( 动画, {

	补间：{
		“*”：[函数（道具，价值）{
			var tween = this.createTween(prop, value);
			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
			返回补间；
		} ]
	},

	tweener：功能（道具，回调）{
		如果（isFunction（道具））{
			回调=道具；
			道具 = [“*”];
		} 别的 {
			props = props.match(rnothtmlwhite);
		}

		变种道具，
			指数 = 0,
			length = props.length;

		for (; index < length; index++) {
			道具 = 道具 [索引];
			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
			Animation.tweeners[ prop ].unshift( callback );
		}
	},

	前置过滤器：[ defaultPrefilter ],

	前置过滤器：函数（回调，前置）{
		如果（前置）{
			Animation.prefilters.unshift(回调);
		} 别的 {
			Animation.prefilters.push(回调);
		}
	}
});

jQuery.speed = function（速度，缓动，fn）{
	var opt = speed && typeof speed === “对象” ? jQuery.extend（{}，速度）：{
		完成：fn || !fn && 缓动 ||
			isFunction( 速度 ) && 速度,
		持续时间：速度，
		缓动：fn && 缓动 || 缓动 && !isFunction( 缓动 ) && 缓动
	};

	// 如果 fx 关闭则转到结束状态
	如果（jQuery.fx.off）{
		opt.duration = 0;

	} 别的 {
		如果（typeof opt.duration！==“数字”）{
			如果（jQuery.fx.speeds 中的 opt.duration）{
				opt.duration = jQuery.fx.speeds[opt.duration];

			} 别的 {
				opt.duration = jQuery.fx.speeds._default;
			}
		}
	}

	// 标准化 opt.queue - true/undefined/null -> "fx"
	如果（opt.queue == null || opt.queue === true）{
		opt.queue = "fx";
	}

	// 排队
	opt.old = opt.complete;

	opt.complete = function() {
		如果（isFunction（opt.old））{
			opt.old.call(这个);
		}

		如果（选择队列）{
			jQuery.dequeue(this, opt.queue);
		}
	};

	返回选择；
};

jQuery.fn.extend({
	fadeTo: function( speed, to, easing, callback ) {

		// 将不透明度设置为 0 后显示任何隐藏的元素
		return this.filter(isHiddenWithinTree).css("不透明度", 0).show()

			// 动画到指定的值
			.end().animate( { opacity: to }, speed, easing, callback );
	},
	动画：功能（道具，速度，缓动，回调）{
		var empty = jQuery.isEmptyObject(prop),
			optall = jQuery.speed（速度，缓动，回调），
			doAnimation = function() {

				// 对 prop 的副本进行操作，这样每个属性的缓动就不会丢失
				var anim = Animation(this, jQuery.extend({}, prop), optall);

				// 清空动画，或完成立即解析
				如果（空 || dataPriv.get（这个，“完成”））{
					动画停止（真）；
				}
			};

		doAnimation.finish = doAnimation;

		返回空 || optall.queue === false ？
			这个.each( doAnimation ) :
			this.queue(optall.queue, doAnimation);
	},
	停止：函数（类型，clearQueue，gotoEnd）{
		var stopQueue = 函数（挂钩）{
			var stop = hooks.stop;
			删除 hooks.stop；
			停止（转到结束）；
		};

		如果（类型类型！==“字符串”）{
			gotoEnd = clearQueue;
			清除队列=类型；
			类型 = 未定义；
		}
		如果（清除队列）{
			this.queue(类型 || "fx", [] );
		}

		返回 this.each( 函数() {
			变种出队=真，
				index = type != null && type + "queueHooks",
				计时器 = jQuery.timers,
				data = dataPriv.get(这个);

			如果（指数）{
				如果（数据[索引]&&数据[索引].停止）{
					停止队列（数据[索引]）；
				}
			} 别的 {
				for（数据中的索引）{
					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
						停止队列（数据[索引]）；
					}
				}
			}

			对于 ( index = timers.length; index--; ) {
				if ( timers[ index ].elem === 这个 &&
					( type == null || timers[ index ].queue === type ) ) {

					定时器[索引].anim.stop(gotoEnd);
					出列=假；
					timers.splice( 索引, 1 );
				}
			}

			// 如果没有强制执行最后一步，则启动队列中的下一个。
			// 计时器当前将调用它们的完整回调，这
			// 将出列，但前提是它们是 gotoEnd。
			如果（出队||！gotoEnd）{
				jQuery.dequeue（这个，类型）；
			}
		});
	},
	完成：函数（类型）{
		如果（类型！==假）{
			类型 = 类型 || “外汇”；
		}
		返回 this.each( 函数() {
			变量索引，
				data = dataPriv.get( 这个 ),
				队列=数据[类型+“队列”]，
				hooks = data[ 类型 + "queueHooks" ],
				计时器 = jQuery.timers,
				长度=队列？队列长度：0；

			// 在私有数据上启用完成标志
			数据完成=真；

			// 先清空队列
			jQuery.queue( 这个, 类型, [] );

			如果（挂钩 && hooks.stop）{
				hooks.stop.call(this, true);
			}

			// 寻找任何活跃的动画，并完成它们
			对于 ( index = timers.length; index--; ) {
				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
					定时器[索引].anim.stop(真);
					timers.splice( 索引, 1 );
				}
			}

			// 查找旧队列中的任何动画并完成它们
			对于（索引= 0；索引<长度；索引++）{
				如果（队列[索引]&&队列[索引].完成）{
					队列[索引].finish.call(这个);
				}
			}

			// 关闭完成标志
			删除数据。完成；
		});
	}
});

jQuery.each( [ "切换", "显示", "隐藏" ], function( _i, name ) {
	var cssFn = jQuery.fn[名称];
	jQuery.fn[ name ] = function( speed, easing, callback ) {
		返回速度== null || typeof speed === “布尔值” ?
			cssFn.apply（这个，参数）：
			this.animate( genFx( name, true ), speed, easing, callback );
	};
});

// 为自定义动画生成快捷方式
jQuery.each({
	slideDown：genFx（“显示”），
	slideUp: genFx( "隐藏" ),
	slideToggle：genFx（“切换”），
	淡入：{不透明度：“显示”}，
	fadeOut：{不透明度：“隐藏”}，
	fadeToggle：{不透明度：“切换”}
}, 函数(名称, 道具) {
	jQuery.fn[ name ] = function( speed, easing, callback ) {
		返回 this.animate(props, speed, easing, callback );
	};
});

jQuery.timers = [];
jQuery.fx.tick = function() {
	可变定时器，
		我 = 0,
		计时器 = jQuery.timers;

	fxNow = Date.now();

	对于 (; i < timers.length; i++ ) {
		定时器=定时器[我];

		// 运行计时器并在完成后安全地移除它（允许外部移除）
		如果（！定时器（）&&定时器[我] ===定时器）{
			timers.splice( i--, 1 );
		}
	}

	如果（！timers.length）{
		jQuery.fx.stop();
	}
	fxNow = 未定义；
};

jQuery.fx.timer = 函数（定时器）{
	jQuery.timers.push(定时器);
	jQuery.fx.start();
};

jQuery.fx.interval = 13;
jQuery.fx.start = function() {
	如果（进行中）{
		返回;
	}

	进行中=真；
	日程（）;
};

jQuery.fx.stop = function() {
	进行中=空；
};

jQuery.fx.speeds = {
	慢：600，
	快：200，

	// 默认速度
	_默认值：400
};


// 基于 Clint Helfers 的插件，并获得许可。
jQuery.fn.delay = 函数（时间，类型）{
	时间 = jQuery.fx ？jQuery.fx.speeds[ 时间 ] || 时间：时间；
	类型 = 类型 || “外汇”；

	返回 this.queue（类型，函数（下一个，钩子）{
		var timeout = window.setTimeout(next, time);
		hooks.stop = function() {
			window.clearTimeout(超时);
		};
	});
};


（ 功能（） {
	var input = document.createElement("输入"),
		select = document.createElement( "选择" ),
		opt = select.appendChild( document.createElement( "option" ) );

	input.type = "复选框";

	// 支持：仅限 Android <=4.3
	// 复选框的默认值应该是“on”
	support.checkOn = input.value !== "";

	// 支持：仅限 IE <=11
	// 必须访问 selectedIndex 才能选择默认选项
	support.optSelected = opt.selected;

	// 支持：仅限 IE <=11
	// 一个 input 在变成一个 radio 之后就失去了它的价值
	input = document.createElement("输入");
	input.value = "t";
	input.type = "收音机";
	support.radioValue = input.value === "t";
} )();


var boolHook,
	attrHandle = jQuery.expr.attrHandle;

jQuery.fn.extend({
	属性：函数（名称，值）{
		返回访问（这个，jQuery.attr，名称，值，arguments.length > 1）;
	},

	removeAttr：功能（名称）{
		返回 this.each( 函数() {
			jQuery.removeAttr( 这个, 名字 );
		});
	}
});

jQuery.扩展（{
	属性：函数（元素，名称，值）{
		var ret, 钩子,
			nType = elem.nodeType;

		// 不要在文本、注释和属性节点上获取/设置属性
		如果（nType === 3 || nType === 8 || nType === 2）{
			返回;
		}

		// 当不支持属性时回退到 prop
		如果 (typeof elem.getAttribute === "undefined") {
			返回 jQuery.prop(elem, name, value);
		}

		// 属性钩子由小写版本决定
		// 如果已定义，则获取必要的钩子
		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
				（jQuery.expr.match.bool.test（名称）？boolHook：未定义）；
		}

		如果（价值！==未定义）{
			如果（值=== null）{
				jQuery.removeAttr(元素, 名称);
				返回;
			}

			if ( hooks && "set" in hooks &&
				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
				返还；
			}

			elem.setAttribute( 名称, 值 + "" );
			返回值；
		}

		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
			返还；
		}

		ret = jQuery.find.attr(元素, 名称);

		// 不存在的属性返回null，我们归一化为undefined
		返回 ret == null ？未定义：ret；
	},

	属性钩子：{
		类型： {
			设置：函数（元素，值）{
				如果 (!support.radioValue && value === "radio" &&
					节点名（元素，“输入”））{
					var val = elem.value;
					elem.setAttribute("类型", 值);
					如果（值）{
						elem.value = val;
					}
					返回值；
				}
			}
		}
	},

	removeAttr：函数（元素，值）{
		变种名称，
			我 = 0,

			// 属性名称可以包含非 HTML 空白字符
			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
			attrNames = value && value.match( rnothtmlwhite );

		如果（属性名 && elem.nodeType === 1）{
			while ( ( name = attrNames[ i++ ] ) ) {
				elem.removeAttribute(名称);
			}
		}
	}
});

// 布尔属性的钩子
布尔钩子 = {
	设置：函数（元素，值，名称）{
		如果（值===假）{

			// 设置为 false 时删除布尔属性
			jQuery.removeAttr(元素, 名称);
		} 别的 {
			elem.setAttribute(名称, 名称);
		}
		返回名称；
	}
};

jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function(_i, name){
	var getter = attrHandle[名称] || jQuery.find.attr;

	attrHandle[名称] = 函数（元素，名称，isXML）{
		var ret, 句柄,
			lowercaseName = name.toLowerCase();

		如果（！isXML）{

			// 通过暂时从 getter 中删除此函数来避免无限循环
			handle = attrHandle[ 小写名称 ];
			attrHandle[ 小写名称 ] = ret;
			ret = getter(elem, name, isXML) != null ?
				小写名称：
				无效的;
			attrHandle[ lowercaseName ] = handle;
		}
		返还；
	};
});




var rfocusable = /^(?:input|select|textarea|button)$/i,
	rcclickable = /^(?:a|area)$/i;

jQuery.fn.extend({
	道具：功能（名称，价值）{
		返回访问（这个，jQuery.prop，名称，值，arguments.length > 1）;
	},

	removeProp：函数（名称）{
		返回 this.each( 函数() {
			删除这个[ jQuery.propFix[ name ] || 姓名 ];
		});
	}
});

jQuery.扩展（{
	道具：功能（元素，名称，值）{
		var ret, 钩子,
			nType = elem.nodeType;

		// 不要获取/设置文本、注释和属性节点的属性
		如果（nType === 3 || nType === 8 || nType === 2）{
			返回;
		}

		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {

			// 修复名称并附加钩子
			名称 = jQuery.propFix[ 名称 ] || 姓名;
			hooks = jQuery.propHooks[名称];
		}

		如果（价值！==未定义）{
			if ( hooks && "set" in hooks &&
				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
				返还；
			}

			返回（元素[名称]=值）；
		}

		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
			返还；
		}

		返回 elem[ 名称 ];
	},

	proHooks: {
		标签索引：{
			得到：函数（元素）{

				// 支持：仅限 IE <=9 - 11
				// elem.tabIndex 并不总是返回
				// 未明确设置时的正确值
				// 使用适当的属性检索 (trac-12072)
				var tabindex = jQuery.find.attr( elem, "tabindex" );

				如果（标签索引）{
					返回 parseInt(tabindex, 10);
				}

				如果 （
					rfocusable.test(elem.nodeName) ||
					rcclickable.test(elem.nodeName)&&
					元素.href
				) {
					返回 0；
				}

				返回-1；
			}
		}
	},

	道具修复：{
		“对于”：“htmlFor”，
		“类”：“类名”
	}
});

// 支持：仅限 IE <=11
// 访问 selectedIndex 属性
// 强制浏览器遵守选择的设置
// 在选项上
// getter 确保默认选项被选中
// 当在一个 optgroup 中时
// 此代码禁用 eslint 规则“no-unused-expressions”
// 因为它考虑了这样的加入 noop
如果（！support.optSelected）{
	jQuery.propHooks.selected = {
		得到：函数（元素）{

			/* eslint no-unused-expressions: "off" */

			var parent = elem.parentNode;
			如果（父 && parent.parentNode）{
				parent.parentNode.selectedIndex;
			}
			返回空值；
		},
		设置：函数（元素）{

			/* eslint no-unused-expressions: "off" */

			var parent = elem.parentNode;
			如果（父母）{
				parent.selectedIndex;

				如果（父节点。父节点）{
					parent.parentNode.selectedIndex;
				}
			}
		}
	};
}

jQuery.each( [
	“标签索引”，
	“只读”，
	“最长长度”，
	“细胞间距”，
	“细胞填充”，
	“行跨度”，
	“colSpan”，
	"使用地图",
	“框架边框”，
	“内容可编辑”
]， 功能（） {
	jQuery.propFix[ this.toLowerCase() ] = this;
});




	// 根据 HTML 规范去除和折叠空格
	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
	函数 stripAndCollapse( 值 ) {
		var tokens = value.match(rnothtmlwhite) || [];
		返回 tokens.join("");
	}


函数 getClass(元素){
	返回 elem.getAttribute && elem.getAttribute( "class" ) || "";
}

函数 classesToArray( 值 ) {
	如果（Array.isArray（价值））{
		返回值；
	}
	如果（类型值===“字符串”）{
		返回值匹配（rnothtmlwhite）|| [];
	}
	返回 [];
}

jQuery.fn.extend({
	添加类：函数（值）{
		var classNames, cur, curValue, className, i, finalValue;

		如果（isFunction（价值））{
			返回 this.each( 函数( j ) {
				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
			});
		}

		classNames = classesToArray( 值 );

		如果（类名.长度）{
			返回 this.each( 函数() {
				curValue = getClass(这个);
				cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );

				如果（当前）{
					for ( i = 0; i < classNames.length; i++ ) {
						类名 = 类名[我];
						如果（cur.indexOf（“”+类名+“”）<0）{
							当前 += 类名 + " ";
						}
					}

					// 只有在不同时才赋值，以避免不必要的渲染。
					finalValue = stripAndCollapse(cur);
					如果（curValue！== finalValue）{
						this.setAttribute( "class", finalValue );
					}
				}
			});
		}

		归还这个；
	},

	removeClass：函数（值）{
		var classNames, cur, curValue, className, i, finalValue;

		如果（isFunction（价值））{
			返回 this.each( 函数( j ) {
				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
			});
		}

		如果（！arguments.length）{
			return this.attr( "类", "" );
		}

		classNames = classesToArray( 值 );

		如果（类名.长度）{
			返回 this.each( 函数() {
				curValue = getClass(这个);

				// 这个表达式是为了更好的压缩性（见 addClass）
				cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );

				如果（当前）{
					for ( i = 0; i < classNames.length; i++ ) {
						类名 = 类名[我];

						// 删除*所有*实例
						while ( cur.indexOf( " " + className + " " ) > -1 ) {
							cur = cur.replace( " " + className + " ", " " );
						}
					}

					// 只有在不同时才赋值，以避免不必要的渲染。
					finalValue = stripAndCollapse(cur);
					如果（curValue！== finalValue）{
						this.setAttribute( "class", finalValue );
					}
				}
			});
		}

		归还这个；
	},

	toggleClass：函数（值，stateVal）{
		变种类名，类名，我，自我，
			类型 = 类型值，
			isValidValue = 类型 === “字符串” || Array.isArray( 值 );

		如果（isFunction（价值））{
			返回 this.each( 函数( i ) {
				jQuery( 这个 ).toggleClass(
					value.call(this, i, getClass(this), stateVal),
					状态值
				);
			});
		}

		if ( typeof stateVal === "boolean" && isValidValue ) {
			返回状态值？this.addClass( 值 ) : this.removeClass( 值 );
		}

		classNames = classesToArray( 值 );

		返回 this.each( 函数() {
			如果（isValidValue）{

				// 切换单个类名
				self = jQuery(这个);

				for ( i = 0; i < classNames.length; i++ ) {
					类名 = 类名[我];

					// 检查给定的每个类名，空格分隔的列表
					如果（self.hasClass（类名））{
						self.removeClass(类名);
					} 别的 {
						self.addClass(类名);
					}
				}

			// 切换整个类名
			} else if ( value === undefined || type === "boolean" ) {
				类名 = getClass(这个);
				如果（类名）{

					// 如果设置了则存储类名
					dataPriv.set( 这个, "__className__", className );
				}

				// 如果元素有一个类名，或者如果我们传递给 `false`，
				// 然后删除整个类名（如果有的话，上面保存了它）。
				// 否则带回之前保存的内容（如果有的话），
				// 如果没有存储任何内容，则回退到空字符串。
				如果（this.setAttribute）{
					this.setAttribute("类",
						类名 || 价值===假？
							“”：
							dataPriv.get( 这个, "__className__" ) || “”
					);
				}
			}
		});
	},

	hasClass：函数（选择器）{
		var 类名, elem,
			我 = 0;

		类名 = " " + 选择器 + " ";
		while ( ( elem = this[ i++ ] ) ) {
			如果 (elem.nodeType === 1 &&
				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
				返回真；
			}
		}

		返回假；
	}
});




var rreturn = /\r/g;

jQuery.fn.extend({
	val：函数（值）{
		var hooks, ret, valueIsFunction,
			元素=这个[0]；

		如果（！arguments.length）{
			如果（元素）{
				hooks = jQuery.valHooks[ elem.type ] ||
					jQuery.valHooks[ elem.nodeName.toLowerCase() ];

				如果 ( 挂钩 &&
					在钩子中“获取”&&
					( ret = hooks.get( elem, "value" ) ) !== undefined
				) {
					返还；
				}

				ret = elem.value;

				// 处理最常见的字符串情况
				如果（typeof ret ===“字符串”）{
					返回 ret.replace( rreturn, "" );
				}

				// 处理值为 null/undef 或数字的情况
				返回 ret == null ？“”：退役；
			}

			返回;
		}

		valueIsFunction = isFunction( 值 );

		返回 this.each( 函数( i ) {
			变量值；

			如果（this.nodeType！== 1）{
				返回;
			}

			如果（valueIsFunction）{
				val = value.call( this, i, jQuery( this ).val() );
			} 别的 {
				val = 值；
			}

			// 将 null/undefined 视为 ""; 将数字转换为字符串
			如果（val == null）{
				val = "";

			} else if ( typeof val === "number" ) {
				val += "";

			} else if ( Array.isArray( val ) ) {
				val = jQuery.map( val, function( 值 ) {
					返回值==空？“”：价值+“”；
				});
			}

			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];

			// 如果 set 返回 undefined，则退回到正常设置
			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
				这个.value = val;
			}
		});
	}
});

jQuery.扩展（{
	valHooks：{
		选项： {
			得到：函数（元素）{

				var val = jQuery.find.attr(elem, "value");
				返回值！=空？
					值：

					// 支持：仅限 IE <=10 - 11
					// option.text 抛出异常 (trac-14686, trac-14858)
					// 剥离和折叠空白
					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
					stripAndCollapse(jQuery.text(elem));
			}
		},
		选择： {
			得到：函数（元素）{
				变量值，选项，我，
					选项 = elem.options,
					index = elem.selectedIndex,
					one = elem.type === "选择一个",
					值=一？无效的 ： []，
					最大=一？index + 1 : options.length;

				如果（索引 < 0）{
					我=最大值；

				} 别的 {
					我=一？指数：0；
				}

				// 遍历所有选中的选项
				对于（；我<最大；我++）{
					选项=选项[我]；

					// 支持：仅限 IE <=9
					// IE8-9 在表单重置后不更新选择 (trac-2551)
					如果 ( ( option.selected || i === index ) &&

							// 不要返回禁用的或禁用的选项组中的选项
							!option.disabled &&
							( !option.parentNode.disabled ||
								!nodeName( option.parentNode, "optgroup" ) ) ) {

						// 获取选项的具体值
						value = jQuery( option ).val();

						// 我们不需要一个数组来进行一次选择
						如果一个 ） {
							返回值；
						}

						// 多选返回一个数组
						值.push(值);
					}
				}

				返回值；
			},

			设置：函数（元素，值）{
				var optionSet, 选项,
					选项 = elem.options,
					values = jQuery.makeArray( value ),
					i = options.length;

				当我 -  ） {
					选项=选项[我]；

					/* eslint-disable no-cond-assign */

					如果（选项。选择=
						jQuery.inArray( jQuery.valHooks.option.get( 选项 ), 值 ) > -1
					) {
						选项设置=真；
					}

					/* eslint-enable no-cond-assign */
				}

				// 强制浏览器在设置不匹配值时表现一致
				如果（！optionSet）{
					elem.selectedIndex = -1;
				}
				返回值；
			}
		}
	}
});

// 收音机和复选框 getter/setter
jQuery.each( [ "radio", "checkbox" ], function() {
	jQuery.valHooks[ 这个 ] = {
		设置：函数（元素，值）{
			如果（Array.isArray（价值））{
				返回 ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
			}
		}
	};
	如果 (!support.checkOn) {
		jQuery.valHooks[ this ].get = function( elem ) {
			返回 elem.getAttribute("value") === null ？“开”：elem.value；
		};
	}
});




// 返回仅包含属性的 jQuery
var location = window.location;

var nonce = { guid: Date.now() };

var rquery = ( /\?/ );



// 跨浏览器xml解析
jQuery.parseXML = 函数（数据）{
	var xml, parserErrorElem;
	如果（！数据||数据类型！==“字符串”）{
		返回空值；
	}

	// 支持：仅限 IE 9 - 11
	// IE 抛出无效输入的 parseFromString。
	尝试 {
		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
	} 抓住 (e) {}

	parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];
	如果（！xml || parserErrorElem）{
		jQuery.error( "无效的 XML: " + (
			解析器错误元素？
				jQuery.map(parserErrorElem.childNodes, function(el){
					返回 el.textContent；
				} ).join( "\n" ) :
				数据
		));
	}
	返回 xml；
};


var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
	stopPropagationCallback = function( e ) {
		e.stopPropagation();
	};

jQuery.extend(jQuery.event, {

	触发器：函数（事件、数据、elem、onlyHandlers）{

		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
			事件路径 = [ 元素 || 文档 ]，
			type = hasOwn.call( event, "type" ) ? 事件类型：事件，
			命名空间 = hasOwn.call( 事件，“命名空间”) ? event.namespace.split( "." ) : [];

		cur = lastElement = tmp = elem = elem || 文档;

		// 不要在文本和评论节点上做事件
		如果（elem.nodeType === 3 || elem.nodeType === 8）{
			返回;
		}

		// focus/blur 变形为 focusin/out；确保我们现在不解雇他们
		如果（rfocusMorph.test（类型+ jQuery.event.triggered））{
			返回;
		}

		如果 ( type.indexOf( "." ) > -1 ) {

			// 命名空间触发器；创建一个正则表达式以匹配 handle() 中的事件类型
			命名空间 = type.split( "." );
			type = namespaces.shift();
			命名空间.sort();
		}
		ontype = type.indexOf( ":" ) < 0 && "on" + type;

		// Caller 可以传入一个 jQuery.Event 对象，Object，或者只是一个事件类型字符串
		事件 = 事件 [jQuery.expando] ?
			事件 ：
			new jQuery.Event(类型, typeof event === "object" && event );

		// 触发位掩码：& 1 用于本机处理程序；& 2 用于 jQuery（始终为真）
		event.isTrigger = onlyHandlers ？2 : 3;
		event.namespace = namespaces.join( "." );
		event.rnamespace = event.namespace ?
			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
			无效的;

		// 清除事件以防它被重用
		事件.result = 未定义；
		如果 (!event.target) {
			event.target = elem;
		}

		// 克隆任何传入数据并添加事件，创建处理程序 arg 列表
		数据 = 数据 == 空？
			[ 事件 ] ：
			jQuery.makeArray(数据, [事件]);

		// 允许特殊事件绘制到线外
		special = jQuery.event.special[类型] || {};
		如果（！onlyHandlers && special.trigger && special.trigger.apply（elem，数据）=== false）{
			返回;
		}

		// 根据 W3C 事件规范 (trac-9951) 提前确定事件传播路径
		//冒泡到文档，然后到窗口；观察全局所有者文档 var (trac-9724)
		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {

			bubbleType = special.delegateType || 类型;
			如果（！rfocusMorph.test（bubbleType +类型））{
				cur = cur.parentNode;
			}
			对于 ( ; cur; cur = cur.parentNode ) {
				eventPath.push(cur);
				tmp = 当前；
			}

			// 只有在我们需要文档时才添加窗口（例如，不是普通的 obj 或分离的 DOM）
			如果（tmp ===（elem.ownerDocument || 文件））{
				eventPath.push( tmp.defaultView || tmp.parentWindow || 窗口);
			}
		}

		// 在事件路径上触发处理程序
		我 = 0;
		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
			最后一个元素 = 当前；
			事件类型 = i > 1 ?
				泡泡类型：
				特殊.bindType || 类型;

			// jQuery 处理程序
			handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] &&
				dataPriv.get(cur, "句柄");
			如果（句柄）{
				handle.apply(cur, 数据);
			}

			// 本机处理程序
			handle = ontype && cur[ ontype ];
			如果（处理 && handle.apply && acceptData（当前））{
				event.result = handle.apply(cur, data);
				如果（事件。结果===假）{
					事件.preventDefault();
				}
			}
		}
		事件类型 = 类型；

		// 如果没有人阻止默认操作，现在就执行
		如果 ( !onlyHandlers && !event.isDefaultPrevented() ) {

			如果（（！special._default ||
				special._default.apply( eventPath.pop(), data ) === false ) &&
				接受数据（元素））{

				// 在目标上调用与事件同名的本机 DOM 方法。
				// 不要在窗口上执行默认操作，这是全局变量所在的位置 (trac-6170)
				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {

					// 当我们调用它的 FOO() 方法时，不要重新触发 onFOO 事件
					tmp = elem[ ontype ];

					如果（tmp）{
						elem[ ontype ] = null;
					}

					// 防止再次触发同一个事件，因为我们已经在上面冒泡了
					jQuery.event.triggered = 类型；

					如果 ( event.isPropagationStopped() ) {
						lastElement.addEventListener（类型，stopPropagationCallback）；
					}

					elem[ 类型 ]();

					如果 ( event.isPropagationStopped() ) {
						lastElement.removeEventListener（类型，stopPropagationCallback）；
					}

					jQuery.event.triggered = undefined;

					如果（tmp）{
						elem[ ontype ] = tmp;
					}
				}
			}
		}

		返回事件.result；
	},

	// 搭载捐赠者事件以模拟不同的事件
	// 仅用于 `focus(in | out)` 事件
	模拟：函数（类型，元素，事件）{
		var e = jQuery.extend(
			新的 jQuery.Event(),
			事件，
			{
				类型：类型，
				isSimulated：真
			}
		);

		jQuery.event.trigger(e, null, elem);
	}

});

jQuery.fn.extend({

	触发器：函数（类型，数据）{
		返回 this.each( 函数() {
			jQuery.event.trigger（类型，数据，这个）；
		});
	},
	触发器处理程序：函数（类型，数据）{
		var elem = this[0];
		如果（元素）{
			返回 jQuery.event.trigger（类型、数据、elem、true）；
		}
	}
});


变量
	rbracket = /\[\]$/,
	rCRLF = /\r?\n/g,
	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
	rsubmittable = /^(?:input|select|textarea|keygen)/i;

函数 buildParams（前缀、obj、传统、添加）{
	变量名称；

	如果（Array.isArray（obj））{

		// 序列化数组项。
		jQuery.each( obj, function( i, v ) {
			如果（传统 || rbracket.test（前缀））{

				// 将每个数组项视为一个标量。
				添加（前缀，v）；

			} 别的 {

				// Item 是非标量（数组或对象），对其数字索引进行编码。
				构建参数（
					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
					五，
					传统的，
					添加
				);
			}
		});

	} else if ( !traditional && toType( obj ) === "object" ) {

		// 序列化对象项。
		对于（对象中的名称）{
			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
		}

	} 别的 {

		// 序列化标量项。
		添加（前缀，对象）；
	}
}

// 序列化一个表单元素数组或一组
// 键/值到查询字符串
jQuery.param = function(a, traditional){
	var 前缀，
		小号 = [],
		添加=函数（键，值或函数）{

			// 如果 value 是一个函数，调用它并使用它的返回值
			变量值 = isFunction(valueOrFunction) ?
				价值或功能（）：
				价值或功能；

			s[ s.length ] = encodeURIComponent( key ) + "=" +
				encodeURIComponent（值==空？“”：值）；
		};

	如果（a == null）{
		返回 ””;
	}

	// 如果传入的是数组，则假定它是表单元素的数组。
	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {

		// 序列化表单元素
		jQuery.each( a, function() {
			添加（this.name，this.value）;
		});

	} 别的 {

		// 如果是传统的，编码“旧”方式（1.3.2 或更早的方式
		// 做到了），否则递归编码参数。
		for ( a 中的前缀 ) {
			buildParams（前缀，a[前缀]，传统的，添加）；
		}
	}

	// 返回结果序列化
	返回 s.join("&");
};

jQuery.fn.extend({
	序列化：函数（）{
		返回 jQuery.param(this.serializeArray());
	},
	序列化数组：函数（）{
		返回 this.map( 函数() {

			// 可以为“elements”添加propHook来过滤或添加表单元素
			var elements = jQuery.prop( this, "elements" );
			返回元素？jQuery.makeArray（元素）：这个；
		} ).filter( 函数() {
			var type = this.type;

			// 使用 .is( ":disabled" ) 以便 fieldset[disabled] 起作用
			返回 this.name && !jQuery( this ).is( ":disabled" ) &&
				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( 类型 ) &&
				( this.checked || !rcheckableType.test( 类型 ) );
		} ).map( 函数( _i, elem ) {
			var val = jQuery( this ).val();

			如果（val == null）{
				返回空值；
			}

			如果（Array.isArray（val））{
				返回 jQuery.map(val, function(val){
					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
				});
			}

			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
		} ）。得到（）;
	}
});


变量
	r20 = /%20/克,
	rhash = /#.*$/,
	rantiCache = /([?&])_=[^&]*/,
	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,

	// trac-7653、trac-8125、trac-8152：本地协议检测
	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
	rnoContent = /^(?:GET|HEAD)$/,
	rprotocol = /^\/\//,

	/* 前置过滤器
	 * 1) 它们对于引入自定义数据类型很有用（示例参见 ajax/jsonp.js）
	 * 2）这些被称为：
	 * - 在要求交通工具之前
	 * - 参数序列化后（如果 s.processData 为真，则 s.data 为字符串）
	 * 3) 键是数据类型
	 * 4) 可以使用包罗万象的符号“*”
	 * 5) 执行将从传输数据类型开始，然后在需要时继续执行“*”
	 */
	前置过滤器 = {},

	/* 传输绑定
	 * 1) 键是数据类型
	 * 2) 可以使用包罗万象的符号“*”
	 * 3) 选择将从传输数据类型开始，然后在需要时转到“*”
	 */
	运输= {}，

	// 避免注释序言字符序列 (trac-10098); 必须安抚 lint 并避免压缩
	allTypes = "*/".concat( "*" ),

	// 用于解析文档来源的锚标记
	originAnchor = document.createElement( "a" );

originAnchor.href = location.href;

// jQuery.ajaxPrefilter 和 jQuery.ajaxTransport 的基础“构造函数”
函数 addToPrefiltersOrTransports（结构）{

	// dataTypeExpression 是可选的，默认为“*”
	返回函数（数据类型表达式，函数）{

		如果（类型数据类型表达式！==“字符串”）{
			func = 数据类型表达式；
			数据类型表达式 = "*";
		}

		var 数据类型，
			我 = 0,
			dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || [];

		如果（isFunction（函数））{

			// 对于 dataTypeExpression 中的每个数据类型
			while ( ( dataType = dataTypes[ i++ ] ) ) {

				// 如果有请求则添加
				如果（数据类型[0]===“+”）{
					数据类型 = 数据类型.slice( 1 ) || "*";
					(结构[数据类型]=结构[数据类型]||[]).unshift(func);

				// 否则追加
				} 别的 {
					(结构[数据类型]=结构[数据类型]||[]).push(func);
				}
			}
		}
	};
}

// 预过滤器和传输的基本检查功能
功能 inspectPrefiltersOrTransports（结构，选项，originalOptions，jqXHR）{

	变种检查= {}，
		seekingTransport = ( 结构 === 运输 );

	功能检查（数据类型）{
		变种选择;
		检查[数据类型]=真；
		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
			if ( typeof dataTypeOrTransport === "字符串" &&
				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {

				options.dataTypes.unshift( dataTypeOrTransport );
				检查（数据类型或传输）；
				返回假；
			} else if ( seekingTransport ) {
				返回！（选择=数据类型或传输）；
			}
		});
		返回选择；
	}

	返回检查（选项。数据类型[0]）|| !inspected[ "*" ] && inspect( "*" );
}

// ajax 选项的特殊扩展
// 采用“平面”选项（不进行深度扩展）
// 修复 trac-9887
函数ajaxExtend（目标，源）{
	变种键，深，
		flatOptions = jQuery.ajaxSettings.flatOptions || {};

	对于（在 src 中键入）{
		如果（源[键]！==未定义）{
			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src [ key ];
		}
	}
	如果（深）{
		jQuery.extend(true, target, deep);
	}

	返回目标；
}

/* 处理对 ajax 请求的响应：
 * - 找到正确的数据类型（介于内容类型和预期数据类型之间）
 * - 返回相应的响应
 */
函数 ajaxHandleResponses(s, jqXHR, responses) {

	var ct, 类型, finalDataType, firstDataType,
		内容 = s.内容，
		dataTypes = s.dataTypes;

	// 去掉auto dataType，并在这个过程中获取content-type
	while ( dataTypes[ 0 ] === "*" ) {
		数据类型.shift();
		如果（ct ===未定义）{
			ct = s.mimeType || jqXHR.getResponseHeader("内容类型");
		}
	}

	// 检查我们是否正在处理已知的内容类型
	如果（CT）{
		for（输入内容）{
			如果（内容[类型]&&内容[类型].test（ct））{
				dataTypes.unshift( 类型 );
				休息;
			}
		}
	}

	// 检查我们是否有预期数据类型的响应
	如果（响应中的数据类型[0]）{
		finalDataType = dataTypes[0];
	} 别的 {

		// 尝试可转换的数据类型
		对于（输入回复）{
			如果（！dataTypes[0]||s.converters[类型+“”+dataTypes[0]]）{
				最终数据类型 = 类型；
				休息;
			}
			如果（！firstDataType）{
				第一个数据类型 = 类型；
			}
		}

		// 或者只使用第一个
		最终数据类型 = 最终数据类型 || 第一个数据类型；
	}

	// 如果我们找到一个数据类型
	// 如果需要，我们将数据类型添加到列表中
	// 并返回相应的响应
	如果（最终数据类型）{
		如果（最终数据类型！==数据类型[0]）{
			dataTypes.unshift(finalDataType);
		}
		返回响应[最终数据类型]；
	}
}

/* 给定请求和原始响应的链式转换
 * 同时在 jqXHR 实例上设置 responseXXX 字段
 */
函数 ajaxConvert（s，响应，jqXHR，isSuccess）{
	var conv2, 当前, conv, tmp, prev,
		转换器 = {},

		// 使用 dataTypes 的副本，以防我们需要修改它以进行转换
		dataTypes = s.dataTypes.slice();

	// 使用小写键创建转换器映射
	如果（数据类型[1]）{
		for ( conv in s.converters ) {
			converters[conv.toLowerCase()] = s.converters[conv];
		}
	}

	当前 = dataTypes.shift();

	// 转换为每个顺序数据类型
	而（当前）{

		如果（s.responseFields[当前]）{
			jqXHR[ s.responseFields[ 当前 ] ] = 响应；
		}

		// 如果提供，应用数据过滤器
		如果（！prev && isSuccess && s.dataFilter）{
			响应 = s.dataFilter( 响应, s.dataType );
		}

		上一个=当前；
		当前 = dataTypes.shift();

		如果（当前）{

			// 如果当前数据类型是非自动的，那么只有工作要做
			如果（当前===“*”）{

				当前 = 上一个；

			// 如果 prev dataType 为非自动且与当前不同，则转换响应
			} else if ( prev !== "*" && prev !== current ) {

				// 寻找直接转换器
				conv = converters[prev + " " + current] || 转换器[“*”+当前]；

				// 如果没有找到，寻找一对
				如果（！conv）{
					对于（转换器中的 conv2）{

						// 如果conv2输出电流
						tmp = conv2.split( " " );
						如果（tmp[1]===当前）{

							// 如果 prev 可以转换为可接受的输入
							conv = converters[prev + " " + tmp[0]] ||
								转换器[“*”+ tmp[0]]；
							如果（转换）{

								// 压缩等价转换器
								如果（转换===真）{
									conv = 转换器[conv2];

								// 否则，插入中间数据类型
								} else if ( converters[conv2] !== true ) {
									当前 = tmp[0]；
									dataTypes.unshift( tmp[ 1 ] );
								}
								休息;
							}
						}
					}
				}

				// 应用转换器（如果不是等价的）
				如果（转换！==真）{

					// 除非允许错误冒泡，否则捕获并返回它们
					如果（conv && s.throws）{
						响应=转换（响应）；
					} 别的 {
						尝试 {
							响应=转换（响应）；
						} 赶上 ( e ) {
							返回 {
								状态：“解析器错误”，
								错误：转换？e : "没有从 " + prev + " 到 " + current 的转换
							};
						}
					}
				}
			}
		}
	}

	返回{状态：“成功”，数据：响应}；
}

jQuery.扩展（{

	// 用于保存活动查询数量的计数器
	活动：0，

	// 下次请求的 Last-Modified 头缓存
	上一次更改： {}，
	电子标签：{}，

	ajax设置：{
		网址：location.href，
		输入：“获取”，
		isLocal: rlocalProtocol.test( location.protocol ),
		全球：真实，
		过程数据：真，
		异步：真，
		contentType: "application/x-www-form-urlencoded; charset=UTF-8",

		/*
		超时：0，
		数据：空，
		数据类型：空，
		用户名：空，
		密码：空，
		缓存：空，
		抛出：错误，
		传统的：假的，
		标头：{}，
		*/

		接受：{
			“*“： 所有类型，
			文本：“文本/纯文本”，
			html: "文本/html",
			xml: "应用程序/xml, 文本/xml",
			json：“应用程序/json，文本/javascript”
		},

		内容： {
			xml: /\bxml\b/,
			html: /\bhtml/,
			json: /\bjson\b/
		},

		响应字段：{
			xml：“响应XML”，
			文本：“响应文本”，
			JSON：“responseJSON”
		},

		// 数据转换器
		// 键用单个空格分隔源（或包罗万象的“*”）和目标类型
		转换器：{

			// 将任何内容转换为文本
			“*文本”：字符串，

			// 文本到 html（true = 无转换）
			“文本 html”：正确，

			// 将文本评估为 json 表达式
			“文本 json”：JSON.parse，

			// 将文本解析为 xml
			“文本 xml”：jQuery.parseXML
		},

		// 对于不应深度扩展的选项：
		// 你可以在这里添加你自己的自定义选项
		// 当你创建一个不应该的
		// 深度扩展（参见 ajaxExtend）
		平面选项：{
			网址：真实，
			上下文：真实
		}
	},

	// 在目标中创建一个完整的设置对象
	// 同时包含 ajaxSettings 和设置字段。
	// 如果省略目标，则写入 ajaxSettings。
	ajaxSetup：函数（目标，设置）{
		返回设置？

			// 构建一个设置对象
			ajaxExtend（ajaxExtend（目标，jQuery.ajaxSettings），设置）：

			// 扩展 ajaxSettings
			ajaxExtend(jQuery.ajaxSettings, target);
	},

	ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
	ajaxTransport：addToPrefiltersOrTransports（传输），

	// 主要方法
	ajax：函数（网址，选项）{

		// 如果 url 是一个对象，模拟 pre-1.5 签名
		如果（typeof url ===“对象”）{
			选项=网址；
			网址=未定义；
		}

		// 强制选项成为一个对象
		选项=选项|| {};

		可变运输，

			// 没有反缓存参数的 URL
			缓存网址，

			// 响应头
			响应标题字符串，
			响应头，

			// 超时句柄
			超时定时器，

			// 网址清理变量
			网址锚点，

			// 请求状态（发送时变为假，完成时变为真）
			完全的，

			// 知道是否要调度全局事件
			火球，

			// 循环变量
			我，

			// 未缓存的 url 部分
			未缓存，

			// 创建最终选项对象
			s = jQuery.ajaxSetup({}, 选项),

			// 回调上下文
			callbackContext = s.context || 秒，

			// 全局事件的上下文是 callbackContext 如果它是 DOM 节点或 jQuery 集合
			globalEventContext = s.context &&
				（callbackContext.nodeType || callbackContext.jquery）？
				jQuery（回调上下文）：
				jQuery.事件，

			// 延迟
			延迟 = jQuery.Deferred(),
			completeDeferred = jQuery.Callbacks( "一次记忆" ),

			// 状态相关的回调
			statusCode = s.statusCode || {},

			// 标头（它们是一次性发送的）
			requestHeaders = {},
			requestHeadersNames = {},

			// 默认中止消息
			strAbort = "取消",

			// 假 xhr
			jqXHR = {
				就绪状态：0，

				// 如果需要，构建标头哈希表
				getResponseHeader：函数（键）{
					变量匹配；
					如果（完成）{
						如果（！responseHeaders）{
							responseHeaders = {};
							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
								responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
										.concat(匹配[2]);
							}
						}
						match = responseHeaders[ key.toLowerCase() + " " ];
					}
					返回匹配 == null ？null : match.join(", ");
				},

				// 原始字符串
				getAllResponseHeaders：函数（）{
					返回完成？响应头字符串：空；
				},

				// 缓存头部
				setRequestHeader：函数（名称，值）{
					如果（完成==空）{
						name = requestHeadersNames[ name.toLowerCase() ] =
							requestHeadersNames[ name.toLowerCase() ] || 姓名;
						requestHeaders[ 名称 ] = 值；
					}
					归还这个；
				},

				// 覆盖响应内容类型标头
				overrideMimeType：函数（类型）{
					如果（完成==空）{
						s.mimeType = 类型；
					}
					归还这个；
				},

				// 状态相关的回调
				状态码：函数（地图）{
					可变代码；
					如果（地图）{
						如果（完成）{

							// 执行适当的回调
							jqXHR.always(地图[jqXHR.status]);
						} 别的 {

							// 以保留旧回调的方式延迟添加新回调
							对于（地图中的代码）{
								statusCode[code] = [statusCode[code], map[code]];
							}
						}
					}
					归还这个；
				},

				// 取消请求
				中止：功能（状态文本）{
					var finalText = 状态文本 || 中止；
					如果（运输）{
						运输中止（最终文本）；
					}
					完成（0，最终文本）；
					归还这个；
				}
			};

		// 附加延迟
		deferred.promise(jqXHR);

		// 如果没有提供则添加协议（预过滤器可能需要它）
		// 处理设置对象中的虚假 url（trac-10093：与旧签名一致）
		// 如果可用，我们也使用 url 参数
		s.url = ( ( url || s.url || location.href ) + "" )
			.replace(rprotocol, location.protocol + "//" );

		// 根据票证 trac-12004 键入的别名方法选项
		s.type = options.method || 选项类型 || s.方法|| s.类型；

		// 提取数据类型列表
		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];

		// 当源与当前源不匹配时，跨域请求是有序的。
		如果（s.crossDomain == null）{
			urlAnchor = document.createElement( "a" );

			// 支持：IE <=8 - 11，Edge 12 - 15
			// 如果 url 格式不正确，IE 会在访问 href 属性时抛出异常，
			// 例如 http://example.com:80x/
			尝试 {
				urlAnchor.href = s.url;

				// 支持：仅限 IE <=8 - 11
				// 当 s.url 是 relative 时，Anchor 的 host 属性设置不正确
				urlAnchor.href = urlAnchor.href;
				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
					urlAnchor.protocol + "//" + urlAnchor.host;
			} 赶上 ( e ) {

				// 如果解析 URL 出错，假设是 crossDomain，
				// 如果它无效，它可以被传输拒绝
				s.crossDomain = true;
			}
		}

		// 如果还不是字符串则转换数据
		if ( s.data && s.processData && typeof s.data !== "string" ) {
			s.data = jQuery.param( s.data, s.traditional );
		}

		// 应用前置过滤器
		inspectPrefiltersOrTransports（前置过滤器，s，选项，jqXHR）；

		// 如果请求在前置过滤器中被中止，则停在那里
		如果（完成）{
			返回jqXHR；
		}

		// 如果需要，我们现在可以触发全局事件
		// 如果 jQuery.event 在 AMD 使用场景中未定义，则不要触发事件 (trac-15118)
		fireGlobals = jQuery.event && s.global;

		// 观察一组新的请求
		如果（fireGlobals && jQuery.active++ === 0）{
			jQuery.event.trigger("ajaxStart");
		}

		// 大写类型
		s.type = s.type.toUpperCase();

		// 判断请求是否有内容
		s.hasContent = !rnoContent.test( s.type );

		// 保存 URL 以防我们玩弄 If-Modified-Since
		// 和/或稍后的 If-None-Match 标头
		// 删除散列以简化 url 操作
		cacheURL = s.url.replace( rhash, "" );

		// 更多选项处理没有内容的请求
		如果（！s.hasContent）{

			// 记住哈希，这样我们就可以把它放回去
			uncached = s.url.slice(cacheURL.length);

			// 如果数据可用并且应该被处理，则将数据附加到 url
			如果 ( s.data && ( s.processData || typeof s.data === "string" ) ) {
				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;

				// trac-9682: 删除数据，这样它就不会在最终的重试中使用
				删除数据；
			}

			// 如果需要，添加或更新反缓存参数
			如果（s.cache === false）{
				cacheURL = cacheURL.replace(rantiCache, "$1");
				未缓存 = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
					未缓存；
			}

			// 将哈希和反缓存放在将被请求的 URL 上 (gh-1732)
			s.url = cacheURL + 未缓存；

		// 如果这是编码形式的正文内容，则将 '%20' 更改为 '+' (gh-2658)
		} else if ( s.data && s.processData &&
			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
			s.data = s.data.replace( r20, "+" );
		}

		// 如果处于 ifModified 模式，则设置 If-Modified-Since 和/或 If-None-Match 标头。
		如果（s.ifModified）{
			如果 (jQuery.lastModified[cacheURL]){
				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
			}
			如果 (jQuery.etag[cacheURL]){
				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
			}
		}

		// 如果正在发送数据，则设置正确的标头
		如果（s.data && s.hasContent && s.contentType !== false || options.contentType）{
			jqXHR.setRequestHeader( "Content-Type", s.contentType );
		}

		// 根据数据类型设置服务器的 Accepts 标头
		jqXHR.setRequestHeader(
			“接受”，
			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
				s.accepts[ s.dataTypes[ 0 ] ] +
					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ):
				s.接受[“*”]
		);

		// 检查标题选项
		对于（我在 s.headers 中）{
			jqXHR.setRequestHeader( i, s.headers[ i ] );
		}

		// 允许自定义标头/mimetypes 和提前中止
		如果 ( s.beforeSend &&
			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || 完成) ) {

			// 如果尚未完成则中止并返回
			返回 jqXHR.abort();
		}

		// 中止不再是取消
		strAbort = "中止";

		// 在 deferreds 上安装回调
		completeDeferred.add( s.complete );
		jqXHR.done( s.success );
		jqXHR.fail( s.error );

		// 获取交通工具
		transport = inspectPrefiltersOrTransports（传输，s，选项，jqXHR）;

		// 如果没有传输，我们自动中止
		如果（！运​​输）{
			完成（-1，“禁止运输”）；
		} 别的 {
			jqXHR.readyState = 1;

			// 发送全局事件
			如果（fireGlobals）{
				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
			}

			// 如果请求在 ajaxSend 中被中止，则停在那里
			如果（完成）{
				返回jqXHR；
			}

			// 暂停
			如果 ( s.async && s.timeout > 0 ) {
				timeoutTimer = window.setTimeout(函数(){
					jqXHR.abort("超时");
				}, 超时时间);
			}

			尝试 {
				完成=假；
				transport.send(requestHeaders, done);
			} 赶上 ( e ) {

				// 重新抛出完成后的异常
				如果（完成）{
					扔 e;
				}

				// 传播其他作为结果
				完成（-1，e）；
			}
		}

		// 一切完成时的回调
		功能完成（状态，nativeStatusText，响应，标题）{
			var isSuccess，成功，错误，响应，修改，
				statusText = nativeStatusText;

			// 忽略重复调用
			如果（完成）{
				返回;
			}

			完成=真；

			// 如果存在则清除超时
			如果（超时定时器）{
				window.clearTimeout(timeoutTimer);
			}

			// 为早期垃圾收集取消引用传输
			//（无论 jqXHR 对象将被使用多长时间）
			运输=未定义；

			// 缓存响应头
			responseHeadersString = 标题 || "";

			// 设置就绪状态
			jqXHR.readyState = status > 0 ? 4 : 0;

			//判断是否成功
			isSuccess = 状态 >= 200 && 状态 < 300 || 状态 === 304；

			// 获取响应数据
			如果（回应）{
				response = ajaxHandleResponses(s, jqXHR, responses);
			}

			// 对缺少的脚本使用 noop 转换器，但如果是 jsonp 则不使用
			如果 (!isSuccess &&
				jQuery.inArray( "脚本", s.dataTypes ) > -1 &&
				jQuery.inArray( "json", s.dataTypes ) < 0 ) {
				s.converters[ "文本脚本" ] = function() {};
			}

			// 无论如何转换（这样 responseXXX 字段总是被设置）
			response = ajaxConvert(s, response, jqXHR, isSuccess);

			// 如果成功，处理类型链接
			如果（成功）{

				// 如果处于 ifModified 模式，则设置 If-Modified-Since 和/或 If-None-Match 标头。
				如果（s.ifModified）{
					modified = jqXHR.getResponseHeader( "Last-Modified" );
					如果（修改）{
						jQuery.lastModified[ cacheURL ] = 已修改；
					}
					modified = jqXHR.getResponseHeader( "etag" );
					如果（修改）{
						jQuery.etag[ cacheURL ] = 已修改；
					}
				}

				// 如果没有内容
				如果（状态=== 204 || s.type ===“HEAD”）{
					statusText = "无内容";

				// 如果没有修改
				} 否则如果（状态=== 304）{
					statusText = "未修改";

				// 如果我们有数据，让我们转换它
				} 别的 {
					statusText = response.state;
					成功=响应.数据；
					错误=响应.错误；
					isSuccess = !error;
				}
			} 别的 {

				// 从 statusText 中提取错误并对非中止进行规范化
				错误=状态文本；
				如果（状态 || !statusText）{
					statusText = "错误";
					如果（状态<0）{
						状态 = 0；
					}
				}
			}

			// 为假的 xhr 对象设置数据
			jqXHR.status = 状态；
			jqXHR.statusText = ( nativeStatusText || statusText ) + "";

			// 成功/错误
			如果（成功）{
				deferred.resolveWith(callbackContext, [成功, statusText, jqXHR]);
			} 别的 {
				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
			}

			// 状态相关的回调
			jqXHR.statusCode(statusCode);
			状态代码=未定义；

			如果（fireGlobals）{
				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
					[ jqXHR, s, isSuccess ? 成功：错误]）；
			}

			// 完全的
			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );

			如果（fireGlobals）{
				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );

				// 处理全局 AJAX 计数器
				如果（！（--jQuery.active））{
					jQuery.event.trigger( "ajaxStop" );
				}
			}
		}

		返回jqXHR；
	},

	getJSON: function(url, data, callback) {
		返回 jQuery.get(url, data, callback, "json");
	},

	getScript：函数（网址，回调）{
		返回 jQuery.get(url, undefined, callback, "script");
	}
});

jQuery.each( [ "get", "post" ], function( _i, 方法) {
	jQuery[ 方法 ] = 函数（网址、数据、回调、类型）{

		// 如果省略了数据参数，则转移参数
		如果（isFunction（数据））{
			类型 = 类型 || 打回来;
			回调=数据；
			数据=未定义；
		}

		// url 可以是一个选项对象（然后必须有 .url）
		返回 jQuery.ajax( jQuery.extend( {
			网址：网址，
			类型：方法，
			数据类型：类型，
			数据：数据，
			成功：回调
		}, jQuery.isPlainObject( url ) && url ) );
	};
});

jQuery.ajaxPrefilter(函数(s){
	变量我；
	对于（我在 s.headers 中）{
		如果（i.toLowerCase（）===“内容类型”）{
			s.contentType = s.headers[ i ] || "";
		}
	}
});


jQuery._evalUrl = function(url, options, doc) {
	返回 jQuery.ajax({
		网址：网址，

		// 明确说明，因为用户可以通过 ajaxSetup (trac-11264) 覆盖它
		输入：“获取”，
		数据类型：“脚本”，
		缓存：真，
		异步：错误，
		全球：假的，

		// 仅在成功时评估响应 (gh-4126)
		// dataFilter 不会为失败响应调用，所以使用它代替
		// 默认转换器是笨拙的，但它可以工作。
		转换器：{
			“文本脚本”：函数（）{}
		},
		数据过滤器：函数（响应）{
			jQuery.globalEval（响应，选项，文档）；
		}
	});
};


jQuery.fn.extend({
	wrapAll：函数（html）{
		变种换行；

		如果（这个[0]）{
			如果（isFunction（html）））{
				html = html.call(this[0]);
			}

			// 包裹目标的元素
			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );

			如果（这个[0].parentNode）{
				wrap.insertBefore(this[0]);
			}

			wrap.map(函数(){
				变量 elem = 这个；

				while ( elem.firstElementChild ) {
					elem = elem.firstElementChild;
				}

				返回元素；
			} ).append(这个);
		}

		归还这个；
	},

	wrapInner：函数（html）{
		如果（isFunction（html）））{
			返回 this.each( 函数( i ) {
				jQuery( this ).wrapInner( html.call( this, i ) );
			});
		}

		返回 this.each( 函数() {
			var self = jQuery( 这个 ),
				内容 = self.contents();

			如果（内容。长度）{
				内容.wrapAll(html);

			} 别的 {
				self.append(html);
			}
		});
	},

	包装：函数（html）{
		var htmlIsFunction = isFunction(html);

		返回 this.each( 函数( i ) {
			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
		});
	},

	展开：函数（选择器）{
		this.parent( selector ).not( "body" ).each( function() {
			jQuery(this).replaceWith(this.childNodes);
		});
		归还这个；
	}
});


jQuery.expr.pseudos.hidden = 函数（元素）{
	返回 !jQuery.expr.pseudos.visible( elem );
};
jQuery.expr.pseudos.visible = function(元素){
	返回!!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};




jQuery.ajaxSettings.xhr = function() {
	尝试 {
		返回新窗口.XMLHttpRequest();
	} 抓住 (e) {}
};

var xhrSuccessStatus = {

		// 文件协议总是产生状态码 0，假设为 200
		0: 200,

		// 支持：仅限 IE <=9
		// trac-1450: 有时 IE 返回 1223 而它应该是 204
		1223: 204
	},
	xhrSupported = jQuery.ajaxSettings.xhr();

support.cors = !!xhrSupported &&（xhrSupported 中的“withCredentials”）；
support.ajax = xhrSupported = !!xhrSupported;

jQuery.ajaxTransport(函数(选项){
	变种回调，错误回调；

	// 只有在通过 XMLHttpRequest 支持时才允许跨域
	如果（support.cors || xhrSupported && !options.crossDomain）{
		返回 {
			发送：函数（标题，完成）{
				变量我，
					xhr = options.xhr();

				xhr.open(
					选项。类型，
					选项.url,
					选项.async,
					options.username,
					选项.密码
				);

				// 如果提供，应用自定义字段
				如果（选项.xhrFields）{
					对于（我在 options.xhrFields 中）{
						xhr[ i ] = options.xhrFields [ i ];
					}
				}

				// 如果需要，覆盖 mime 类型
				如果（options.mimeType && xhr.overrideMimeType）{
					xhr.overrideMimeType( options.mimeType );
				}

				// X-Requested-With 标头
				// 对于跨域请求，预检的条件是
				// 类似于拼图游戏，我们根本就不会将其设置为确定。
				//（它总是可以在每个请求的基础上设置，甚至可以使用 ajaxSetup）
				// 对于同域请求，如果已经提供，则不会更改标头。
				如果 ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
					headers[ "X-Requested-With" ] = "XMLHttpRequest";
				}

				// 设置标题
				对于（标题中的我）{
					xhr.setRequestHeader( i, headers[ i ] );
				}

				// 打回来
				回调=函数（类型）{
					返回函数（）{
						如果（回调）{
							callback = errorCallback = xhr.onload =
								xhr.onerror = xhr.onabort = xhr.ontimeout =
									xhr.onreadystatechange = null;

							如果（类型===“中止”）{
								xhr.abort();
							}否则如果（类型===“错误”）{

								// 支持：仅限 IE <=9
								// 在手动本机中止时，IE9 抛出
								// 任何非 readyState 的属性访问错误
								如果（typeof xhr.status ！==“数字”）{
									完成（0，“错误”）；
								} 别的 {
									完全的（

										// 文件：协议总是产生状态 0；参见 trac-8605、trac-14207
										xhr.status,
										xhr.statusText
									);
								}
							} 别的 {
								完全的（
									xhrSuccessStatus[ xhr.status ] || xhr.status,
									xhr.statusText,

									// 支持：仅限 IE <=9
									// IE9 没有 XHR2 但会抛出二进制 (trac-11426)
									// 对于 XHR2 非文本，让调用者处理它 (gh-2498)
									( xhr.responseType || “文本”) !== “文本” ||
									typeof xhr.responseText !== "string" ？
										{二进制：xhr.response}：
										{ 文本：xhr.responseText },
									xhr.getAllResponseHeaders()
								);
							}
						}
					};
				};

				// 监听事件
				xhr.onload = 回调();
				errorCallback = xhr.onerror = xhr.ontimeout = callback("error");

				// 支持：仅 IE 9
				// 用 onreadystatechange 代替 onabort
				// 处理未捕获的中止
				如果（xhr.onabort！==未定义）{
					xhr.onabort = errorCallback;
				} 别的 {
					xhr.onreadystatechange = function() {

						// 在超时前检查 readyState 变化
						如果（xhr.readyState === 4）{

							// 允许首先调用 onerror，
							// 但不会处理本机中止
							// 另外，将 errorCallback 保存到一个变量
							// 因为无法访问 xhr.onerror
							window.setTimeout(函数(){
								如果（回调）{
									错误回调（）；
								}
							});
						}
					};
				}

				// 创建中止回调
				回调=回调（“中止”）;

				尝试 {

					// 发送请求（这可能引发异常）
					xhr.send( options.hasContent && options.data || null );
				} 赶上 ( e ) {

					// trac-14683: 只有在还没有被通知为错误时才重新抛出
					如果（回调）{
						扔 e;
					}
				}
			},

			中止：功能（）{
				如果（回调）{
					打回来（）;
				}
			}
		};
	}
});




// 当没有提供明确的数据类型时防止自动执行脚本（参见 gh-2432）
jQuery.ajaxPrefilter(函数(s){
	如果（s.crossDomain）{
		s.contents.script = false;
	}
});

// 安装脚本数据类型
jQuery.ajaxSetup({
	接受：{
		脚本：“文本/javascript，应用程序/javascript，”+
			“应用程序/ecmascript，应用程序/x-ecmascript”
	},
	内容： {
		脚本：/\b(?:java|ecma)script\b/
	},
	转换器：{
		“文本脚本”：函数（文本）{
			jQuery.globalEval(文本);
			返回文本；
		}
	}
});

// 处理缓存的特例和跨域
jQuery.ajaxPrefilter( "脚本", 函数( s ) {
	如果（s.cache ===未定义）{
		s.cache = false;
	}
	如果（s.crossDomain）{
		s.type = "GET";
	}
});

// 绑定脚本标签 hack transport
jQuery.ajaxTransport( "脚本", 函数( s ) {

	// 此传输仅处理跨域或强制属性请求
	如果 ( s.crossDomain || s.scriptAttrs ) {
		var脚本，回调；
		返回 {
			发送：函数（_，完成）{
				script = jQuery( "<脚本>" )
					.attr( s.scriptAttrs || {} )
					.prop({ 字符集: s.scriptCharset, src: s.url } )
					.on( "加载错误", callback = function( evt ) {
						脚本.remove();
						回调=空；
						如果（事件）{
							完成（evt.type ===“错误”？404：200，evt.type）；
						}
					});

				// 使用原生 DOM 操作来避免我们的 domManip AJAX 欺骗
				document.head.appendChild(脚本[0]);
			},
			中止：功能（）{
				如果（回调）{
					打回来（）;
				}
			}
		};
	}
});




var oldCallbacks = [],
	rjsonp = /(=)\?(?=&|$)|\?\?/;

// 默认的 jsonp 设置
jQuery.ajaxSetup({
	jsonp: "回调",
	jsonpCallback：函数（）{
		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
		这个[回调] = 真；
		返回回调；
	}
});

// 检测、标准化选项并为 jsonp 请求安装回调
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR) {

	var callbackName, 覆盖, responseContainer,
		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
			“网址”：
			typeof s.data === "字符串" &&
				( s.contentType || "" )
					.indexOf("application/x-www-form-urlencoded") === 0 &&
				rjsonp.test( s.data ) && "数据"
		);

	// 如果预期的数据类型是“jsonp”或者我们有一个参数要设置则处理
	如果（jsonProp || s.dataTypes[0] ===“jsonp”）{

		// 获取回调名称，记住与其关联的先前存在的值
		回调名称 = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
			s.jsonpCallback() :
			s.jsonp回调；

		// 将回调插入到 url 或表单数据中
		如果（jsonProp）{
			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
		} else if ( s.jsonp !== false ) {
			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
		}

		// 脚本执行后使用数据转换器获取json
		s.converters[ "script json" ] = function() {
			如果（！responseContainer）{
				jQuery.error( callbackName + " 没有被调用" );
			}
			返回响应容器[0]；
		};

		// 强制 json 数据类型
		s.dataTypes[ 0 ] = "json";

		// 安装回调
		覆盖=窗口[回调名称]；
		窗口[回调名称] =函数（）{
			响应容器 = 参数；
		};

		// 清理函数（在转换器之后触发）
		jqXHR.always(函数(){

			// 如果之前的值不存在 - 删除它
			如果（覆盖===未定义）{
				jQuery( 窗口 ).removeProp( callbackName );

			// 否则恢复先前存在的值
			} 别的 {
				window[ callbackName ] = 覆盖；
			}

			// 保存为免费
			如果（s[回调名称]）{

				// 确保重新使用选项不会搞砸
				s.jsonpCallback = originalSettings.jsonpCallback;

				// 保存回调名称以供将来使用
				oldCallbacks.push(回调名);
			}

			// 如果它是一个函数并且我们有响应则调用
			如果（responseContainer && isFunction（覆盖））{
				覆盖（responseContainer[0]）；
			}

			responseContainer = 覆盖 = 未定义；
		});

		// 委托给脚本
		返回“脚本”；
	}
});




// 支持：仅限 Safari 8
// 在 Safari 8 中通过 document.implementation.createHTMLDocument 创建文档
// 折叠兄弟形式：第二个成为第一个的孩子。
// 因此，必须在 Safari 8 中禁用此安全措施。
// https://bugs.webkit.org/show_bug.cgi?id=137337
support.createHTMLDocument = ( 函数() {
	var body = document.implementation.createHTMLDocument( "" ).body;
	body.innerHTML = "<表单></表单><表单></表单>";
	返回 body.childNodes.length === 2;
} )();


// 参数“data”应该是 html 字符串
// 上下文（可选）：如果指定，片段将在此上下文中创建，
// 默认为文档
// keepScripts（可选）：如果为真，将包含在 html 字符串中传递的脚本
jQuery.parseHTML = function（数据，上下文，keepScripts）{
	如果（数据类型！==“字符串”）{
		返回 [];
	}
	如果（类型上下文===“布尔值”）{
		keepScripts = 上下文；
		上下文=假；
	}

	var base, parsed, 脚本；

	如果（！上下文）{

		// 停止立即执行脚本或内联事件处理程序
		// 通过使用 document.implementation
		如果（支持.createHTMLDocument）{
			context = document.implementation.createHTMLDocument( "" );

			// 为创建的文档设置 base href
			// 所以任何带有 URL 的已解析元素
			// 基于文档的 URL (gh-2965)
			base = context.createElement( "base" );
			base.href = document.location.href;
			context.head.appendChild(基础);
		} 别的 {
			上下文=文档；
		}
	}

	已解析 = rsingleTag.exec(数据);
	脚本 = !keepScripts && [];

	// 单个标签
	如果（解析）{
		return [ context.createElement( parsed[ 1 ] ) ];
	}

	parsed = buildFragment( [数据], 上下文, 脚本);

	如果（脚本&&脚本。长度）{
		jQuery( 脚本 ).remove();
	}

	返回 jQuery.merge([], parsed.childNodes);
};


/**
 * 将 url 加载到页面中
 */
jQuery.fn.load = function(url, params, callback) {
	var 选择器，类型，响应，
		自己=这个，
		off = url.indexOf( " " );

	如果（关闭> -1）{
		选择器 = stripAndCollapse( url.slice( off ) );
		url = url.slice( 0, off );
	}

	// 如果是函数
	如果（isFunction（参数））{

		// 我们假设它是回调
		回调=参数；
		参数 = 未定义；

	// 否则，构建一个参数字符串
	} else if ( params && typeof params === "object" ) {
		类型=“发布”；
	}

	// 如果我们有要修改的元素，则发出请求
	如果（自我。长度> 0）{
		jQuery.ajax({
			网址：网址，

			// 如果“type”变量未定义，则使用“GET”方法。
			// 明确此字段的值，因为
			// 用户可以通过 ajaxSetup 方法覆盖它
			类型：类型|| “得到”，
			数据类型：“html”，
			数据：参数
		} ).done( 函数( responseText ) {

			// 保存响应用于完成回调
			响应=参数；

			self.html( 选择器 ?

				// 如果指定了选择器，则在虚拟 div 中定位正确的元素
				// 排除脚本以避免 IE 的“权限被拒绝”错误
				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( 选择器 ) ：

				// 否则使用完整结果
				响应文本）；

		// 如果请求成功，该函数获取"data", "status", "jqXHR"
		// 但它们会被忽略，因为响应已在上面设置。
		// 如果失败，该函数获取“jqXHR”、“status”、“error”
		} ).always(回调&&函数(jqXHR,状态){
			self.each(函数(){
				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
			});
		});
	}

	归还这个；
};




jQuery.expr.pseudos.animated = function(elem){
	返回 jQuery.grep(jQuery.timers, function(fn){
		返回 elem === fn.elem;
	} ）。长度;
};




jQuery.offset = {
	setOffset: function( elem, options, i ) {
		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
			position = jQuery.css( elem, "position" ),
			curElem = jQuery(元素),
			道具 = {};

		// 首先设置位置，以防顶部/左侧甚至在静态元素上设置
		如果（位置===“静态”）{
			elem.style.position = "相对";
		}

		curOffset = curElem.offset();
		curCSSTop = jQuery.css(elem, "top");
		curCSSLeft = jQuery.css( elem, "left" );
		计算位置=（位置===“绝对”||位置===“固定”）&&
			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;

		// 需要能够计算位置
		// top 或 left 是自动的，位置是绝对的或固定的
		如果（计算位置）{
			curPosition = curElem.position();
			curTop = curPosition.top;
			curLeft = curPosition.left;

		} 别的 {
			curTop = parseFloat(curCSSTop)|| 0;
			curLeft = parseFloat（curCSSLeft）|| 0;
		}

		如果（isFunction（选项））{

			// 在此处使用 jQuery.extend 以允许修改坐标参数 (gh-1848)
			options = options.call(elem, i, jQuery.extend({}, curOffset));
		}

		如果（选项。顶部！=空）{
			props.top = ( options.top - curOffset.top ) + curTop;
		}
		如果（选项。左！=空）{
			props.left = ( options.left - curOffset.left ) + curLeft;
		}

		如果（选项中的“使用”）{
			options.using.call(elem, props);

		} 别的 {
			curElem.css(道具);
		}
	}
};

jQuery.fn.extend({

	// offset() 将元素的边框与文档原点相关联
	偏移量：函数（选项）{

		// 为 setter 保留链接
		如果（参数。长度）{
			返回选项 === 未定义？
				这 ：
				this.each( 函数( i ) {
					jQuery.offset.setOffset（这个，选项，我）;
				});
		}

		var rect, 赢,
			元素=这个[0]；

		如果（！元素）{
			返回;
		}

		// 为断开连接和隐藏（显示：无）元素返回零 (gh-2310)
		// 支持：仅限 IE <=11
		// 在 a 上运行 getBoundingClientRect
		// 断开连接的节点在 IE 中抛出错误
		如果（！elem.getClientRects（）。长度）{
			返回{顶部：0，左侧：0}；
		}

		// 通过将视口滚动添加到视口相关 gBCR 来获取文档相对位置
		rect = elem.getBoundingClientRect();
		win = elem.ownerDocument.defaultView;
		返回 {
			顶部：rect.top + win.pageYOffset，
			左：rect.left + win.pageXOffset
		};
	},

	// position() 将元素的边距框与其父元素的填充框的偏移量相关联
	// 这对应CSS绝对定位的行为
	位置：功能（）{
		如果（！这[0]）{
			返回;
		}

		var offsetParent, offset, 文档,
			元素 = 这个 [ 0 ],
			parentOffset = { top: 0, left: 0 };

		// position:fixed 元素从视口偏移，它本身始终具有零偏移
		如果（jQuery.css（elem，“位置”）===“固定”）{

			// 假设 position:fixed 意味着 getBoundingClientRect 的可用性
			offset = elem.getBoundingClientRect();

		} 别的 {
			offset = this.offset();

			// 考虑到 *real* 偏移父元素，它可以是文档或其根元素
			// 当一个静态定位的元素被识别时
			doc = elem.ownerDocument;
			offsetParent = elem.offsetParent || 文档.文档元素；
			while ( offsetParent &&
				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
				jQuery.css(offsetParent, "位置") === "静态") {

				offsetParent = offsetParent.parentNode;
			}
			如果（offsetParent && offsetParent !== elem && offsetParent.nodeType === 1）{

				// 将边界合并到它的偏移量中，因为它们在它的内容原点之外
				parentOffset = jQuery( offsetParent ).offset();
				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
			}
		}

		// 减去父偏移量和元素边距
		返回 {
			顶部：offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
			左：offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
		};
	},

	// 此方法将在以下情况下返回 documentElement：
	// 1) 对于没有offsetParent的iframe里面的元素，这个方法会返回
	// 父窗口的文档元素
	// 2) 对于隐藏或分离的元素
	// 3) 对于 body 或 html 元素，即在 html 节点的情况下 - 它会返回自己
	//
	// 但这些异常从未作为现实生活中的用例出现
	// 并且可能被认为是更可取的结果。
	//
	// 然而，这个逻辑并不能保证，并且可以在未来的任何时候改变
	offsetParent：函数（）{
		返回 this.map( 函数() {
			var offsetParent = this.offsetParent;

			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
				offsetParent = offsetParent.offsetParent;
			}

			返回 offsetParent || 文档元素；
		});
	}
});

// 创建 scrollLeft 和 scrollTop 方法
jQuery.each({ scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function(方法, prop) {
	var top = "pageYOffset" === prop;

	jQuery.fn[ 方法 ] = 函数（ val ）{
		返回访问（这个，函数（元素，方法，val）{

			// 合并文档和窗口
			变种赢;
			如果（isWindow（元素））{
				赢=元素；
			} else if ( elem.nodeType === 9 ) {
				win = elem.defaultView;
			}

			如果（ val === 未定义）{
				返回赢？win[ prop ] : elem [ 方法 ];
			}

			如果（赢）{
				win.scrollTo(
					！顶部 ？val : win.pageXOffset,
					顶部 ？val : win.pageYOffset
				);

			} 别的 {
				elem[ 方法 ] = val;
			}
		}, 方法, val, arguments.length );
	};
});

// 支持：Safari <=7 - 9.1，Chrome <=37 - 49
// 使用 jQuery.fn.position 添加顶部/左侧的 cssHooks
// Webkit 漏洞：https://bugs.webkit.org/show_bug.cgi?id=29084
// 闪烁错误：https://bugs.chromium.org/p/chromium/issues/detail?id=589347
// getComputedStyle 在为上/左/下/右指定时返回百分比；
// 而不是让 css 模块依赖于 offset 模块，只是在这里检查它
jQuery.each( [ "top", "left" ], function( _i, prop) {
	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
		函数（元素，计算）{
			如果（计算）{
				computed = curCSS( elem, prop );

				// 如果 curCSS 返回百分比，回退到偏移量
				返回 rnumnonpx.test（计算）？
					jQuery( elem ).position()[ prop ] + "px" :
					计算;
			}
		}
	);
});


// 创建 innerHeight、innerWidth、height、width、outerHeight 和 outerWidth 方法
jQuery.each({ 高度：“高度”，宽度：“宽度”}，函数(名称，类型){
	jQuery.each({
		填充：“内部”+名称，
		内容类型，
		"": "外层" + 名称
	}, 函数( defaultExtra, funcName ) {

		// Margin 仅适用于 outerHeight, outerWidth
		jQuery.fn[ funcName ] = function( margin, value ) {
			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
				extra = defaultExtra || （保证金 === 真 || 值 === 真？“保证金”：“边框”）；

			返回访问（这个，函数（元素，类型，值）{
				变种文件；

				如果（isWindow（元素））{

					// $( window ).outerWidth/Height 返回 w/h 包括滚动条 (gh-1729)
					返回 funcName.indexOf（“外部”）=== 0？
						元素[“内部”+名称]：
						elem.document.documentElement[ "客户" + 名称 ];
				}

				// 获取文档的宽度或高度
				如果（elem.nodeType === 9）{
					doc = elem.documentElement;

					// scroll[Width/Height] 或 offset[Width/Height] 或 client[Width/Height],
					// 哪个最大
					返回 Math.max(
						elem.body[“滚动”+名称]，文档[“滚动”+名称]，
						elem.body[ "offset" + name ], doc[ "offset" + name ],
						文档[“客户”+姓名]
					);
				}

				返回值 === 未定义？

					// 获取元素的宽度或高度，请求但不强制 parseFloat
					jQuery.css（元素，类型，额外）：

					// 设置元素的宽度或高度
					jQuery.style(元素、类型、值、额外);
			}，类型，可链接？保证金：未定义，可链接）；
		};
	});
});


jQuery.each( [
	“ajax开始”，
	“ajax停止”，
	“ajax完成”，
	“ajax错误”，
	"ajax成功",
	“ajax发送”
], 函数( _i, 类型 ) {
	jQuery.fn[ 类型 ] = 函数（ fn ）{
		返回 this.on( 类型, fn );
	};
});




jQuery.fn.extend({

	绑定：函数（类型，数据，fn）{
		返回 this.on（类型，空，数据，fn）；
	},
	解除绑定：函数（类型，fn）{
		返回 this.off（类型，null，fn）；
	},

	委托：函数（选择器，类型，数据，fn）{
		返回 this.on( 类型、选择器、数据、fn );
	},
	取消委托：函数（选择器，类型，fn）{

		// ( 命名空间 ) 或 ( 选择器，类型 [, fn] )
		返回 arguments.length === 1 ？
			this.off（选择器，“**”）：
			this.off( 类型, 选择器 || "**", fn );
	},

	悬停：功能（fnOver，fnOut）{
		返回 this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
	}
});

jQuery.each(
	( "blur focus focusin focusout resize scroll click dblclick " +
	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
	"更改选择提交 keydown keypress keyup contextmenu" ).split( " " ),
	函数（_i，名称）{

		// 处理事件绑定
		jQuery.fn[名称] = 函数（数据，fn）{
			返回 arguments.length > 0 ?
				this.on（名称，空，数据，fn）：
				this.trigger(名称);
		};
	}
);




// 支持：仅限 Android <=4.0
// 确保我们修剪 BOM 和 NBSP
// 要求“空白运行”从非空白开始
// 避免引擎尝试在每个空格位置匹配“\s+$”时的 O(N^2) 行为。
var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;

// 将函数绑定到上下文，可选地部分应用任何
// 参数。
// jQuery.proxy 被弃用以促进标准（特别是 Function#bind）
// 但是，它不会很快被删除
jQuery.proxy = function( fn, context ) {
	var tmp, args, 代理；

	如果（类型上下文===“字符串”）{
		tmp = fn[上下文];
		上下文=fn；
		fn = tmp;
	}

	// 快速检查以确定目标在规范中是否可调用
	// 这会抛出一个 TypeError，但我们只会返回 undefined。
	如果（！isFunction（fn））{
		返回未定义；
	}

	// 模拟绑定
	args = slice.call( arguments, 2 );
	代理=功能（）{
		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
	};

	// 将唯一处理程序的 guid 设置为与原始处理程序相同的 guid，以便将其删除
	proxy.guid = fn.guid = fn.guid || jQuery.guid++;

	返回代理；
};

jQuery.holdReady = 函数（保持）{
	如果（保持）{
		jQuery.readyWait++;
	} 别的 {
		jQuery.ready(真);
	}
};
jQuery.isArray = Array.isArray;
jQuery.parseJSON = JSON.parse;
jQuery.nodeName = 节点名；
jQuery.isFunction = isFunction;
jQuery.isWindow = isWindow;
jQuery.camelCase = camelCase;
jQuery.type = toType;

jQuery.now = Date.now;

jQuery.isNumeric = function(obj){

	// 从 jQuery 3.0 开始，isNumeric 仅限于
	// 字符串和数字（​​基元或对象）
	// 可以强制转换为有限的数字 (gh-2662)
	var type = jQuery.type(obj);
	返回（类型===“数字”||类型===“字符串”）&&

		// parseFloat NaNs 数字转换误报 ("")
		// ...但误解了前导数字字符串，尤其是十六进制文字（“0x ...”）
		// 减法将无穷大强制为 NaN
		!isNaN( obj - parseFloat( obj ) );
};

jQuery.trim = 函数（文本）{
	返回文本 == 空？
		“”：
		( text + "" ).replace( rtrim, "$1" );
};



// 注册为命名的 AMD 模块，因为 jQuery 可以与其他模块连接
// 可以使用 define 的文件，但不能通过适当的连接脚本
// 理解匿名 AMD 模块。一个命名的 AMD 是最安全和最强大的
// 注册方式。使用小写 jquery 是因为 AMD 模块名称是
// 从文件名派生，jQuery 通常以小写形式传递
// 文件名。在创建全局后执行此操作，以便如果 AMD 模块需要
// 调用 noConflict 来隐藏这个版本的 jQuery，它会起作用。

// 请注意，为了获得最大的可移植性，非 jQuery 库应该
// 将自己声明为匿名模块，并避免设置全局 if
// AMD 加载程序存在。jQuery 是一个特例。有关详细信息，请参阅
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon

if (typeof define === "function" && define.amd) {
	定义（“jquery”，[]，功能（）{
		返回 jQuery；
	});
}




变量

	// 在覆盖的情况下映射到 jQuery
	_jQuery = window.jQuery,

	// 在覆盖的情况下映射 $
	_$ = 窗口.$;

jQuery.noConflict = 函数（深）{
	如果（窗口。$ === jQuery）{
		窗口。$ = _$；
	}

	如果（深 && window.jQuery === jQuery）{
		window.jQuery = _jQuery;
	}

	返回 jQuery；
};

// 公开 jQuery 和 $ 标识符，即使在 AMD 中也是如此
// (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557)
// 和用于浏览器模拟器的 CommonJS (trac-13566)
如果（typeof noGlobal ===“未定义”）{
	window.jQuery = window.$ = jQuery;
}




返回 jQuery；
});